React函数组件调用setPlayers触发too many re-renders错误求助
问题根本原因
你的死循环报错完全是Game组件的渲染逻辑写法违规导致的:
你在players.map的遍历回调中直接调用了setMoney这个状态更新函数,而React组件渲染过程中调用setState会立刻触发组件重渲染,重渲染又会再次执行players.map、再次调用setMoney,最终形成无限重渲染的死循环,触发too many re-renders报错。
你改成普通变量赋值能绕开问题的原因也很简单:普通变量不属于React的响应式状态,修改它不会触发父组件重渲染,子组件自然也不会跟着重渲染,相当于你主动切断了重渲染链路,但这是有问题的临时方案——后续players数据更新时,子组件不会同步刷新渲染。
而cards状态的map遍历没有报错,是因为你没有在它的遍历回调中调用任何setState操作,符合React的渲染逻辑规则。
修复方案
推荐你直接删掉Game组件里money相关的useState声明,完全不需要把它存成额外状态,直接从props的players中计算取值即可,从根源上避免渲染期调用setState的问题:
// Game.jsx 删掉下面这行 // const [money, setMoney] = useState(0) // 新增计算逻辑,在渲染前直接取值 const currentUser = players.find(v => v.username === username) const money = currentUser ? currentUser.money : 0
同时修改players.map的逻辑,不要在遍历中做状态更新操作:
{players.map((v, i) => { if (v.username !== username){ return ( <PlayerInfo name={v.username} money={v.money} key={i} class="info" /> ) } // 当前用户不需要在这里返回组件,也不要调用setMoney return null })}
如果确实需要把money存为组件内部状态,就把更新逻辑移到useEffect中,仅当players或username变化时才更新money:
useEffect(() => { const currentUser = players.find(v => v.username === username) if (currentUser) { setMoney(currentUser.money) } }, [players, username])
内容的提问来源于stack exchange,提问作者dbrewster
相关产品推荐
相关产品推荐

