React回调函数传参时收到错误值问题排查
React井字棋handleClick获取异常i值的问题解决
问题根源
你遇到的问题和React渲染机制无关,核心是**var声明变量的作用域特性**:
var声明的变量没有块级作用域,整个函数内只会存在一个i的引用。- 循环中创建的箭头函数
() => handleClick(i)并没有保存当前迭代的i值,而是持有对i变量的引用。 - 当循环结束时,
i会执行最后一次i += 3,变成12(因为循环条件是i < 10,最后一次迭代i=9,执行后i=12,不满足条件退出循环)。此时所有点击回调触发时,读取的都是这个最终的i值,导致索引异常。
解决方案
方案1:将var替换为let(推荐)
let具有块级作用域,每次循环迭代都会创建一个独立的i变量,箭头函数会捕获当前迭代的i值:
// 修改循环的变量声明 for (let i = 0; i < 10; i += 3) { // 剩余代码保持不变 }
方案2:用立即执行函数(IIFE)捕获当前i值(兼容旧环境)
如果必须使用var,可以通过立即执行函数为每个回调创建独立作用域,保存当前迭代的i值:
// 以retVal[0]中的Square为例,其他位置同理 <Square value={squares[i]} onSquareClick={(function(currentI) { return () => handleClick(currentI); })(i)} />
额外优化:更简洁的方块生成方式
虽然你提到这是次要问题,但可以参考官方教程暗示的两层循环写法,避免手动处理索引,同时彻底规避循环变量问题:
return ( <> <div className="status">{status}</div> {Array(3).fill(null).map((_, rowIndex) => ( <div key={rowIndex} className="board-row"> {Array(3).fill(null).map((_, colIndex) => { const squareIndex = rowIndex * 3 + colIndex; return ( <Square key={squareIndex} value={squares[squareIndex]} onSquareClick={() => handleClick(squareIndex)} /> ); })} </div> ))} </> );
内容的提问来源于stack exchange,提问作者Mike Lowery
相关产品推荐
相关产品推荐

