You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:34:54