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

React状态变更后组件未重新渲染,点击按钮无法修改网格大小

React网格尺寸不更新的问题原因与解决方案

问题根源

你在Picross组件中用useState(temp_g)初始化网格状态,但React的useState有个关键特性:初始值仅在组件第一次渲染时被赋值。当父组件的size变化,传递给Picross的rows/cols props更新时,组件会重新渲染,temp_g也会重新计算,但useState不会自动用新的temp_g覆盖已有的grid状态——这就是网格尺寸没跟着变的原因。

两种正确实现方式

方式1:移除组件内的useState(你已验证有效)

如果网格不需要后续修改(比如用户点击编辑单元格),完全没必要把temp_g存在组件状态里,直接用计算后的数组渲染即可。这样每次props变化时,temp_g都会重新生成,网格自然会更新:

function Picross({ rows, cols }) {
  let temp_g = new Array(rows);
  for (let i = 0; i < rows; i++) {
    temp_g[i] = new Array(cols);
    for (let j = 0; j < cols; j++) {
      temp_g[i][j] = i + j;
    }
  }

  return (
    <div className="grid col s9">
      {temp_g.map((row, rowIdx) => (
        <div className="blockrows" key={rowIdx}>
          {row.map((val, colIdx) => (
            <Node num={val} key={`${rowIdx}-${colIdx}`} />
          ))}
        </div>
      ))}
    </div>
  );
}

方式2:用useEffect监听props更新状态(需修改网格时用)

如果后续需要让用户修改网格内容,必须把grid存在状态里,这时候要加useEffect监听rows和cols的变化,当尺寸改变时重新生成网格并更新状态:

import { useState, useEffect } from 'react';

function Picross({ rows, cols }) {
  const [grid, updateGrid] = useState([]);

  // 当rows或cols变化时,重新生成网格
  useEffect(() => {
    const newGrid = new Array(rows);
    for (let i = 0; i < rows; i++) {
      newGrid[i] = new Array(cols);
      for (let j = 0; j < cols; j++) {
        newGrid[i][j] = i + j;
      }
    }
    updateGrid(newGrid);
  }, [rows, cols]);

  return (
    <div className="grid col s9">
      {grid.map((row, rowIdx) => (
        <div className="blockrows" key={rowIdx}>
          {row.map((val, colIdx) => (
            <Node num={val} key={`${rowIdx}-${colIdx}`} />
          ))}
        </div>
      ))}
    </div>
  );
}

额外提醒

渲染列表时一定要给每个元素加唯一的key属性,这能让React更高效地更新DOM,避免控制台警告和不必要的性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:47:44