You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:39:58