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

React组件传递数字类型key属性为何返回undefined?

React网格组件状态更新时key为undefined的问题

问题场景

我想要创建一个组件网格,并保存每个组件的状态。初始化了对应网格组件的对象数组cellsGrid,代码如下:

let count = 0;
for(let i = 0; i < 15; i++){
    for(let j = 0; j < 30; j++){
      count++;
      let x = 0;
      if(i % 2 !== 0){
        x = j * WIDTH_OF_CELL + OFFSET_X;
      } else {
        x = j * WIDTH_OF_CELL + OFFSET_X + 24;
      }
      const y = i * HEIGHT_OF_CELL + OFFSET_Y;

      let cell = {
        y: y,
        x: x,
        centerX: x + 25,
        centerY: y + 25,
        state: 0,
        key: count
      }
      cellsGrid.push(cell);
    }
  }

中间组件接收cellsGrid作为prop,映射为Cell组件:

return (
    <div>
      {cellsGrid.map((item) => 
        <Cell 
        key={item.key} 
        postitX={item.x} 
        postitY={item.y} 
        edit={edit} 
        state={item.state} 
        handleClick={handleClick}>
        </Cell>
      )}
    </div>
)

点击单元格时要把state从0更新为1,因此传递了handleClick函数:

const handleClick = (event, state, key, callback) => {
    callback();
    let index = cellsGrid.findIndex(cell => cell.key === key);
    cellsGrid[index].state = state;
  };

Cell组件内部调用该函数:

onClick={event => handleClick(event, currentState.state, key, nextState)}

但点击时抛出错误:

Uncaught TypeError: Cannot set properties of undefined (setting 'state')

打印key和index得到:

输出结果:
undefined
-1

问题原因

  1. React的key属性不传递给组件props:父组件中给Cell设置的key={item.key}是React用于列表渲染的内部标识,不会被传递到Cell组件内部,因此Cell里的key变量是undefined。
  2. 直接修改数组不触发React更新:即便找到正确索引,直接修改cellsGrid[index].state也不会触发组件重新渲染,因为React依赖状态更新机制感知变化。

解决方案

1. 给Cell组件传递cellKey prop

在父组件映射Cell时,额外传递包含key值的prop(比如cellKey):

return (
    <div>
      {cellsGrid.map((item) => 
        <Cell 
        key={item.key} 
        cellKey={item.key} {/* 新增:把key作为组件props传递 */}
        postitX={item.x} 
        postitY={item.y} 
        edit={edit} 
        state={item.state} 
        handleClick={handleClick}>
        </Cell>
      )}
    </div>
)

2. 在Cell组件中使用cellKey

确保Cell组件接收cellKey prop,并在点击时传递给handleClick:

// 以函数组件为例,先解构接收cellKey
const Cell = ({ cellKey, state, handleClick, ...rest }) => {
  // 假设currentState和nextState是组件内部状态
  return (
    <div onClick={event => handleClick(event, currentState.state, cellKey, nextState)}>
      {/* 组件内容 */}
    </div>
  )
}

3. 正确更新React状态

不要直接修改原数组,使用状态更新函数创建新数组(假设cellsGrid是用useState管理的状态):

// 初始化状态
const [cellsGrid, setCellsGrid] = useState(initialCellsGrid);

const handleClick = (event, newState, key, callback) => {
    callback();
    // 生成新数组更新状态,触发重新渲染
    setCellsGrid(prevGrid => 
      prevGrid.map(cell => 
        cell.key === key ? { ...cell, state: newState } : cell
      )
    );
};

修改后,点击单元格就能正确找到对应元素,更新其状态并触发组件重新渲染。

内容的提问来源于stack exchange,提问作者Peartree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:31:34