# 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