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

感谢你读到这里。

这座小站更像一份持续维护的“终端笔记”:记录我解决问题的过程,也记录走过的弯路。

如果这篇内容对你有一点点帮助:

  • 点个赞 / 收藏一下,方便你下次回来继续翻
  • 欢迎在评论区补充你的做法(或者指出我的疏漏)
  • 想持续收到更新:可以订阅 RSS(在页面底部)

我们下篇见。


More Posts

评论

评论 (0)

请先登录后再发表评论

加载中...