React.js遇Too many rerenders报错,国际象棋棋盘开发求助
问题分析
你遇到的"Too many rerenders"错误并非因为64次渲染超出限制,而是代码中存在无限重渲染循环。
错误原因
- 渲染阶段直接调用状态更新函数:你在组件的渲染逻辑(嵌套
map循环)中直接调用setSquare,每次调用都会触发组件重新渲染。而组件重渲染时又会再次执行这些循环并调用setSquare,形成无限循环。 - 错误的状态更新方式:
square是对象类型的状态,你却直接传入字符串(如setSquare(${verticals+horizontals})),这会把状态从对象覆盖成字符串,完全不符合你最初的设计意图。
修复方案
生成棋盘格子不需要使用状态(除非后续需要动态修改格子状态),直接在渲染时生成静态的格子数组即可。如果需要缓存生成结果避免重复计算,可以使用useMemo优化性能。
以下是修正后的代码:
import "./App.css"; import { useMemo } from "react"; function App() { const horizontalLine = ["1", "2", "3", "4", "5", "6", "7", "8"]; const verticalLine = ["a", "b", "c", "d", "e", "f", "g", "h"]; // 使用useMemo缓存格子数组,避免每次渲染重复生成 const squares = useMemo(() => { return verticalLine.flatMap((ver, verIndex) => horizontalLine.map((hor, horIndex) => ({ id: `${ver}${hor}`, ver, hor, verIndex, horIndex, })) ); }, [horizontalLine, verticalLine]); return ( <div className="App"> <div className="chessboard" style={{ display: "grid", gridTemplateColumns: "repeat(8, 50px)", gridTemplateRows: "repeat(8, 50px)" }}> {squares.map((square) => ( <div key={square.id} className={`square ${(square.verIndex + square.horIndex) % 2 === 0 ? "light" : "dark"}`} style={{ width: "50px", height: "50px", display: "flex", alignItems: "center", justifyContent: "center" }} > {square.id} </div> ))} </div> </div> ); } export default App;
关键改进点
- 移除了不必要的
square状态,直接通过useMemo生成包含完整属性的格子数组 - 使用
flatMap替代嵌套map,得到一维的64个格子数组,更便于渲染 - 每个格子保留
id、ver、hor及索引信息,满足后续交互或样式需求 - 添加了基础的棋盘布局样式,直接可以看到黑白相间的格子效果
- 给每个格子添加唯一
key属性,符合React列表渲染的要求
内容的提问来源于stack exchange,提问作者tajgel
相关产品推荐
相关产品推荐

