React中如何向组件函数传入正确的计数器值?
React循环生成Square组件时点击事件传参错误的修复
问题根源
你的代码存在两个关键问题:
- 变量作用域问题:用
var声明循环变量i、j和计数器counter,var是函数级作用域,所有循环迭代的闭包共享同一个变量引用。当点击事件触发时,循环已经结束,变量值都变成了循环的最终结果(i=3,counter=9)。 - 传参错误:你给
handleClick传递的参数是行号i,而不是每个Square对应的正确索引counter,这直接导致点击后拿到错误的位置值。
修复方案
方案1:改用let声明变量并修正传参
将var替换为let(块级作用域),同时确保传递正确的索引值:
export default function Board() { const [squares, setSquares] = useState(Array(9).fill(null)); function handleClick(i) { const nextSquares = squares.slice(); nextSquares[i] = "X"; setSquares(nextSquares); } const boardRows = []; let counter = 0; for (let i = 0; i < 3; i++) { const boardSquares = []; for (let j = 0; j < 3; j++) { // 保存当前迭代的索引,避免闭包捕获变量引用 const currentIndex = counter; boardSquares.push( <Square value={squares[currentIndex]} onSquareClick={() => handleClick(currentIndex)} /> ); counter++; } boardRows.push(<div className="board-row">{boardSquares}</div>); } return boardRows; }
方案2:用数组生成式简化代码(更推荐)
避免手动维护计数器,直接通过行号和列号计算索引,代码更简洁且不易出错:
export default function Board() { const [squares, setSquares] = useState(Array(9).fill(null)); function handleClick(i) { const nextSquares = squares.slice(); nextSquares[i] = "X"; setSquares(nextSquares); } return Array.from({ length: 3 }, (_, rowIndex) => ( <div className="board-row" key={rowIndex}> {Array.from({ length: 3 }, (_, colIndex) => { const index = rowIndex * 3 + colIndex; return ( <Square key={index} value={squares[index]} onSquareClick={() => handleClick(index)} /> ); })} </div> )); }
关键说明
let声明的变量具有块级作用域,每次循环迭代都会创建新的变量实例,闭包会捕获当前迭代的变量值,而不是最终的引用。- 通过行号
rowIndex和列号colIndex计算索引(rowIndex*3 + colIndex),可以精准获取每个Square对应的数组位置,无需手动维护计数器。
内容的提问来源于stack exchange,提问作者Recurrence
相关产品推荐
相关产品推荐

