Home > Net >  my 2D grid does not re-render while using with useState hook. Is there any way to re-render after I
my 2D grid does not re-render while using with useState hook. Is there any way to re-render after I

Time:12-29

Context: I am rendering a 2-dimensional grid, where each cell is a Node object with properties: row, col, isGood. I create the grid and and initialize the initialGrid with a full grid. Now I have onClick action that changes the property of isGood of clicked cell would change and it should render. However even if the change happens and the re-rendering does not happen.

Below is my code.

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;

var grid = [];

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

createNodes();

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

    const handleClick = (rowIndex, colIndex) => {
        initialGrid[rowIndex][colIndex].isGood = true;
        setGrid(initialGrid);
    };

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

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

export default App;

How can I re-render the grid ?

my onClick works and I can see it on console.log however the re-rendering doesnot happen even if I call setGrid

CodePudding user response:

You need to construct a new array in the call to setGrid or React won't realize it needs to re-render. You can do this with the spread operator, adding the individual elements of the old array to your new array:

const handleClick = (rowIndex, colIndex) => {
    initialGrid[rowIndex][colIndex].isGood = true;
    setGrid([...initialGrid]);
};

We're also told React works better if we make the call to setGrid into a function as below, which also works. Personally I'm not sure if this is strictly necessary in this example and the code is arguably less clear:

const handleClick = (rowIndex, colIndex) => {
    initialGrid[rowIndex][colIndex].isGood = true;
    setGrid((ary) => [...ary]);
};
  • Related