| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /**
- * 购物车
- */
- import { useMemo, useState, useCallback } from 'react'
- const initList = [
- { id: 1, name: '算法导论', publish: '2006-9', price: 85, count: 1 },
- { id: 2, name: 'UNIX编程艺术', publish: '2016-2', price: 39, count: 1 },
- { id: 3, name: '编程珠玑', publish: '2020-4', price: 189, count: 1 },
- { id: 4, name: '代码大全', publish: '2013-8', price: 299, count: 1 },
- ]
- export default function Shop() {
- const [books, setBooks] = useState(initList)
- // ★ useMemo:仅 books 变化时重新计算总价
- const total = useMemo(() => {
- return books.reduce((sum, item) => sum + item.count * item.price, 0)
- }, [books])
- // ★ 数量 +1(不可变更新)
- const handleAdd = useCallback((id) => {
- setBooks(prev =>
- prev.map(b => b.id === id ? { ...b, count: b.count + 1 } : b)
- )
- }, [])
- // ★ 数量 -1(最小为 1)
- const handleReduce = useCallback((id) => {
- setBooks(prev =>
- prev.map(b => b.id === id && b.count > 1
- ? { ...b, count: b.count - 1 }
- : b
- )
- )
- }, [])
- // ★ 移除
- const handleRemove = useCallback((id) => {
- if (!window.confirm('确定从购物车中移除当前书籍么')) return
- setBooks(prev => prev.filter(item => item.id !== id))
- }, [])
- return (
- <div>
- <h1>🛒 购物车</h1>
- <table border={1} cellPadding={25} style={{ marginTop: 16, borderCollapse: 'collapse' }}>
- <thead>
- <tr style={{ background: '#f5f5f5' }}>
- <th>#</th>
- <th>书籍名称</th>
- <th>出版日期</th>
- <th>价格</th>
- <th>购买数量</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- {books.map((item, index) => (
- <tr key={item.id}>
- <td>{index + 1}</td>
- <td>{item.name}</td>
- <td>{item.publish}</td>
- <td>¥{item.price}</td>
- <td>
- <button
- disabled={item.count <= 1}
- onClick={() => handleReduce(item.id)}
- >−</button>
- <span style={{ padding: '0 8px' }}>{item.count}</span>
- <button onClick={() => handleAdd(item.id)}>+</button>
- </td>
- <td>
- <button onClick={() => handleRemove(item.id)}>移除</button>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- <h2 style={{ marginTop: 20, color: '#e74c3c' }}>
- 总价格:¥{total}
- </h2>
- </div>
- )
- }
|