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

使用useState时二维网格未重新渲染,如何实现重新渲染?

解决React网格点击不触发重新渲染的问题

问题核心在于你直接修改了state里的对象引用,然后把同一个数组传给setGrid——React靠引用变化判断状态更新,引用没改就不会触发重渲染。

具体修改方案:

  1. 不要直接修改原state数组,先创建网格的副本,修改副本里的属性后再更新状态
  2. 二维数组需要逐层复制,避免修改原数组的引用

修改后的handleClick函数:

const handleClick = (rowIndex, colIndex) => {
    // 创建网格的深副本(逐层复制)
    const newGrid = initialGrid.map(row => [...row]);
    // 修改副本中的节点属性
    newGrid[rowIndex][colIndex].isGood = true;
    // 用新副本更新状态
    setGrid(newGrid);
};

另外,全局变量grid和createNodes的写法可能导致组件初始化时的副作用,建议把网格初始化放到useState的初始化函数里,避免全局变量污染:

// 替换原来的全局grid和createNodes
const createNodes = () => {
    const grid = [];
    for (let row = 0; row < totalRows; ++row) {
        const newRow = [];
        for (let col = 0; col < totalCols; ++col) {
            newRow.push(new Node(row, col));
        }
        grid.push(newRow);
    }
    return grid;
};

// 在组件里初始化state
const [initialGrid, setGrid] = useState(createNodes());

完整修改后的代码:

import { useState } from "react";
import "./App.css";

class Node {
    constructor(x, y) {
        this.row = x;
        this.col = y;
        this.isGood = false;
    }
}

const totalRows = 5;
const totalCols = 5;

const createNodes = () => {
    const grid = [];
    for (let row = 0; row < totalRows; ++row) {
        const newRow = [];
        for (let col = 0; col < totalCols; ++col) {
            newRow.push(new Node(row, col));
        }
        grid.push(newRow);
    }
    return grid;
};

const App = () => {
    const [initialGrid, setGrid] = useState(createNodes());

    const handleClick = (rowIndex, colIndex) => {
        // 创建网格副本
        const newGrid = initialGrid.map(row => [...row]);
        newGrid[rowIndex][colIndex].isGood = true;
        setGrid(newGrid);
    };

    const getNodeClass = (node) => {
        return node.isGood ? "node-good" : "node";
    };

    return (
        <div>
            {initialGrid.map((row, rowIndex) => (
                <div key={rowIndex} className="rows">
                    {row.map((column, columnIndex) => (
                        <div
                            className={getNodeClass(column)}
                            id={`${rowIndex}-${columnIndex}`}
                            key={columnIndex}
                            onClick={() => handleClick(rowIndex, columnIndex)}
                        ></div>
                    ))}
                </div>
            ))}
        </div>
    );
};

export default App;

这样修改后,每次点击都会创建新的数组副本,React检测到state引用变化,就会触发重新渲染,单元格的样式也会跟着更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:01:23