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

ReactJS中为每位玩家实现独立加减计数器的问题求助

React 玩家独立计数器实现方案

问题核心

你当前的问题主要出在两点:

  • 全局的count状态被所有玩家共享,无法实现独立计数
  • 向List组件传递props时,未传入minusCount、plusCount和count,导致组件内这些值为undefined

要实现每位玩家的独立计数器,需要把计数状态绑定到单个玩家的数据项中,而非使用全局状态。以下是具体解决方案:


完整修改代码

import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import './sass/style.scss';

const initialList = [];

const listReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_ITEM':
      // 添加玩家时,将输入的number作为初始count存入玩家对象
      return {
        ...state,
        list: state.list.concat({ 
          name: action.name, 
          count: parseInt(action.number), // 转成数字类型存储
          id: action.id 
        }),
      };
    case 'UPDATE_COUNT':
      // 定位到指定玩家,更新其count值
      return {
        ...state,
        list: state.list.map(player => {
          if (player.id === action.id) {
            return {
              ...player,
              count: player.count + action.change
            };
          }
          return player;
        })
      };
    default:
      throw new Error();
  }
};

export default function App() {
  const [listData, dispatchListData] = React.useReducer(listReducer, {
    list: initialList,
    isShowList: true,
  });
  const [name, setName] = React.useState('');
  const [number, setNumber] = React.useState('');

  function handleChange(event) {
    setName(event.target.value);
  }
  function handleNumber(event) {
    setNumber(event.target.value);
  }
  function handleAdd() {
    if (name && number) {
      dispatchListData({ 
        type: 'ADD_ITEM', 
        name, 
        number, 
        id: uuidv4() 
      });
      setName('');
      setNumber('');
    }
  }

  // 通用更新函数:传入玩家id和增减量(+1/-1)
  function updatePlayerCount(id, change) {
    dispatchListData({
      type: 'UPDATE_COUNT',
      id,
      change
    });
  }

  return (
    <section className="player-list">
      <AddItem
        name={name}
        number={number}
        onChange={handleChange}
        onNumber={handleNumber}
        onAdd={handleAdd}
      />
      <div className="player-information">
        {/* 传递更新函数给List组件 */}
        <List list={listData.list} updateCount={updatePlayerCount} />
      </div>
    </section>
  );
};

const AddItem = ({ number, name, onChange, onNumber, onAdd }) => (
  <form>
    <input type="text" value={name} onChange={onChange} placeholder="玩家姓名" />
    <input type="number" value={number} onChange={onNumber} min="1" max="20" placeholder="初始计数" />
    <button type="button" onClick={onAdd}>
      添加玩家
    </button>
  </form>
);

const List = ({ list, updateCount }) => (
  <div className="player-list">
    <div className="player-list-wrapper">
      {list.map((item) => (
        <div className="player" key={item.id}> {/* key需放在循环最外层元素上 */}
          <p><b>{item.name}</b></p>
          <div className="player-lives">
            {/* 点击时传入当前玩家id和-1 */}
            <button onClick={() => updateCount(item.id, -1)}>-</button>
            <p>{item.count}</p>
            {/* 点击时传入当前玩家id和+1 */}
            <button onClick={() => updateCount(item.id, 1)}>+</button>
          </div>
        </div>
      ))}
    </div>
  </div>
);

关键修改说明

  1. 玩家数据结构调整:每个玩家对象新增count属性,存储自身的当前计数,添加玩家时用输入的number初始化
  2. Reducer扩展:新增UPDATE_COUNT类型的action,通过map遍历玩家列表,定位到目标玩家并更新其count值
  3. 通用更新函数:在App组件中实现updatePlayerCount,接收玩家id和增减量,统一处理计数更新逻辑
  4. 组件props传递:将updatePlayerCount传递给List组件,每个玩家的±按钮通过闭包传入自身id和对应增减量,确保操作的是当前玩家的计数
  5. 列表key规范:将key属性放在循环的最外层div上,符合React列表渲染的性能优化要求

内容的提问来源于stack exchange,提问作者MattHamer5

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:15:10