# react-useReducer

1 min read
Table of Contents

react

购物车

商品单价数量总价操作
小满(只)100
1
100
中满(只)200
1
200
大满(只)300
1
300
import { useReducer, useState } from 'react'
const initData = [
  { name: '小满(只)', price: 100, count: 1, id: 1, isEdit: false },
  { name: '中满(只)', price: 200, count: 1, id: 2, isEdit: false },
  { name: '大满(只)', price: 300, count: 1, id: 3, isEdit: false },
]
type Data = typeof initData
const reducer = (
  state: Data,
  action: {
    type: 'add' | 'sub' | 'delete' | 'edit' | 'blur' | 'update_name'
    id: number
    newName?: string
  }
) => {
  const item = state.find((i) => i.id === action.id)!
  switch (action.type) {
    case 'add':
      item.count++
      return [...state]
    case 'sub':
      item.count = Math.max(0, item.count - 1)
      return [...state]
    case 'delete':
      return state.filter((item) => item.id !== action.id)
    case 'edit':
      item.isEdit = true
      return [...state]
    case 'update_name':
      item.name = action.newName!
      return [...state]
    case 'blur':
      item.isEdit = false
      return [...state]
  }
  return state
}
function App() {
  const [data, dispatch] = useReducer(reducer, initData)
  return (
    <div className="h-120 w-full bg-[#242424]">
      <h1 className="text-xl text-red-200 w-full text-center p-5">购物车</h1>
      <table className="w-4xl text-white mx-auto border border-gray-600">
        <thead>
          <tr>
            <th className="py-4">商品</th>
            <th className="py-4">单价</th>
            <th className="py-4">数量</th>
            <th className="py-4">总价</th>
            <th className="py-4">操作</th>
          </tr>
          {data.map((item) => {
            return (
              <tr key={item.id}>
                <td className="py-4" align="center">
                  {item.isEdit ? (
                    <input
                      value={item.name}
                      onChange={(e) =>
                        dispatch({
                          type: 'update_name',
                          id: item.id,
                          newName: e.currentTarget.value,
                        })
                      }
                      onBlur={() =>
                        dispatch({
                          type: 'blur',
                          id: item.id,
                        })
                      }
                    />
                  ) : (
                    item.name
                  )}
                </td>
                <td className="py-4" align="center">
                  {item.price}
                </td>
                <td className="py-4 flex items-center justify-center gap-2" align="center">
                  <button
                    className="p-4 bg-green-500 cursor-pointer"
                    onClick={() =>
                      dispatch({
                        type: 'add',
                        id: item.id,
                      })
                    }
                  >
                    +
                  </button>
                  <div>{item.count}</div>
                  <button
                    className="p-4 bg-red-500 cursor-pointer"
                    onClick={() =>
                      dispatch({
                        type: 'sub',
                        id: item.id,
                      })
                    }
                  >
                    -
                  </button>
                </td>
                <td className="py-4" align="center">
                  {item.price * item.count}
                </td>
                <td className="py-4 flex gap-5 items-center justify-center" align="center">
                  <button
                    className="cursor-pointer"
                    onClick={() =>
                      dispatch({
                        type: 'edit',
                        id: item.id,
                      })
                    }
                  >
                    编辑
                  </button>
                  <button
                    className="cursor-pointer"
                    onClick={() =>
                      dispatch({
                        type: 'delete',
                        id: item.id,
                      })
                    }
                  >
                    删除
                  </button>
                </td>
              </tr>
            )
          })}
        </thead>
      </table>
    </div>
  )
}
export default App
My avatar

Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.


More Posts

Comments