React.js GroceryApp组件开发:实现商品点赞/点踩投票功能
实现带点赞/点踩功能的GroceryApp组件
核心要求
- 状态仅存储在顶层GroceryApp组件中,避免状态分散
- Product为纯展示型组件,仅通过props接收数据与操作回调函数
- 实现点赞(+)、点踩(-)功能,点击后实时更新对应商品的票数
代码实现
import React, { useState } from 'react'; import ReactDOM from 'react-dom/client'; // 纯展示组件:仅接收props渲染内容 function Product({ name, votes, onUpvote, onDownvote }) { return ( <li> <span>{name}</span> - <span>votes: {votes}</span> <button onClick={onUpvote}>+</button> <button onClick={onDownvote}>-</button> </li> ); } // 顶层组件:维护状态与操作逻辑 function GroceryApp({ initialProducts }) { // 将传入的初始商品列表转为组件内部状态 const [products, setProducts] = useState(initialProducts); // 点赞逻辑:找到目标商品,票数+1 const handleUpvote = (productName) => { setProducts(prevProducts => prevProducts.map(product => product.name === productName ? { ...product, votes: product.votes + 1 } : product ) ); }; // 点踩逻辑:找到目标商品,票数-1(限制最低票数为0) const handleDownvote = (productName) => { setProducts(prevProducts => prevProducts.map(product => product.name === productName ? { ...product, votes: Math.max(product.votes - 1, 0) } : product ) ); }; return ( <ul> {products.map(product => ( <Product key={product.name} name={product.name} votes={product.votes} onUpvote={() => handleUpvote(product.name)} onDownvote={() => handleDownvote(product.name)} /> ))} </ul> ); } // 示例调用 const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <GroceryApp initialProducts={[ { name: "Oranges", votes: 0 }, { name: "Bananas", votes: 0 } ]} /> );
点击效果示例
点击Oranges旁的+按钮后,生成的HTML结构如下:
<div id="root"> <ul> <li> <span>Oranges</span> - <span>votes: 1</span> <button>+</button> <button>-</button> </li> <li> <span>Bananas</span> - <span>votes: 0</span> <button>+</button> <button>-</button> </li> </ul> </div>
内容的提问来源于stack exchange,提问作者Kareem Ezzat
相关产品推荐
相关产品推荐

