React实现球员得分累加功能时totPoints返回undefined问题求助
问题根源
- React 状态更新函数(如
setTotPoints)没有返回值,你将其赋值给球员的totPoints字段,导致老球员再次得分时该字段变为undefined - 全局的
totPoints状态属于多余设计,你需要维护的是每个球员自身的得分累加,全局状态反而干扰了新球员的初始得分计算,导致新球员首次得分就显示2 - 浅拷贝的
players数组内部对象仍为原 state 的引用,直接修改对象属性属于直接变更 state,不符合 React 状态更新规范
修复后代码
import { useState } from 'react'; import { nanoid } from 'nanoid'; function App() { const [number, setNumber] = useState(''); const [scorers, setScorers] = useState([]); const sortedScorers = [...scorers].sort((a, b) => a.number - b.number); const onePointScoredHandler = () => { const targetNumber = +number; const existPlayer = scorers.find(player => player.number === targetNumber); if (existPlayer) { // 老球员得分,更新对应球员的得分,不修改原state const updatedScorers = scorers.map(player => { return player.number === targetNumber ? {...player, totPoints: player.totPoints + 1} : player; }); setScorers(updatedScorers); } else { // 新球员首次得分,初始值直接设为1 const newScorer = { id: nanoid(4), number: targetNumber, totPoints: 1, }; setScorers([...scorers, newScorer]); } setNumber(''); }; return ( <div className="App"> <h4>Individual points</h4> <br /> <br /> <br /> <input type="number" value={number} onChange={(e) => setNumber(e.target.value)} /> <br /> <br /> <button onClick={onePointScoredHandler}>Add 1p</button> <br /> <br /> <table className="table"> <thead> <tr> <th>ID</th> <th>NUMBER</th> <th>Total Points</th> </tr> </thead> <tbody> {sortedScorers.map((player) => ( <tr key={player.id}> <td>{player.id}</td> <td>{player.number}</td> <td>{player.totPoints}</td> </tr> ))} </tbody> </table> </div> ); } export default App;
优化说明
- 删除了冗余的全局
totPoints状态,直接基于每个球员自身的totPoints做累加 - 改用
map生成新的球员数组,避免直接修改原state对象 - 去掉了
tbody中重复的排序逻辑,直接使用已经排序完成的sortedScorers渲染 - 提前将输入的号码转为数字存储,避免重复转换的冗余代码
内容的提问来源于stack exchange,提问作者lelkes
相关产品推荐
相关产品推荐

