0

The following code is updating a grid:

useEffect(() => {
    const { start_row, start_col, end_row, end_col } = FIXED_COORDINATES;
    if (visualize) {
      let path = dfs(grid, `${start_row},${start_col}`, `${end_row},${end_col}`);
      path = path.map(coord => coord.split(",").map(x => parseInt(x)))
      path.forEach(cell => {
        setGrid(makeRoute(grid, cell[0], cell[1]));
      });
      console.log(grid);
    }
  }, [visualize])

The makeRoute function is updating a particular cell in the grid:

export const makeRoute = (grid, row, col) => {
  // Takes the grid and coordinates of a cell and toggles the route property of that cell
  // Returns the modified grid
  let newGrid, newRow, newObj;

  newObj = {...grid[row][col]}; // gets the cell object
  newObj.route = true; // modifies the cell object

  newRow = [...grid[row]]; // gets the row in which the above object resides
  newRow[col] = newObj; // modifies the row

  newGrid = [...grid] // gets the entire grid
  newGrid[row] = newRow // modifies the grid

  return newGrid;
}

So I'm taking the grid, modifying and returning a new grid which I'm trying to save in state with setGrid function within useEffect. However, the value doesn't persist in the state. How can I fix this?

MiniGunnR
  • 5,590
  • 8
  • 42
  • 66
  • state update is asynchronous and state is constant within a particular render of a component. Logging the state right after updating it will log the old state. Use `useEffect` hook to log the state: `useEffect(() => console.log(state), [state]);` – Yousaf Jun 18 '21 at 10:48
  • patience: [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Thomas Jun 18 '21 at 10:48
  • 1
    Not related to your problem but instead of calling `setGrid` inside the `forEach`, first create the final state object and then pass it to the `setGrid` function after the `forEach` method. – Yousaf Jun 18 '21 at 10:51
  • If you change `makeRoute` to `(grid, [row, col]) => {...` then you can do `setGrid(path.reduce(makeRoute, grid));` – Thomas Jun 18 '21 at 10:54
  • @Yousaf The problem is that each `forEach` loop is updating the state, because I can see the result in the app, but the previous update is not persisting. What I am trying to accomplish is change the color of a number of cells by changing their `route` property to true, but only the final cell is changing color because each loop begins with the `base state`, and not the modified state from the previous loop. – MiniGunnR Jun 18 '21 at 20:41
  • Solved it with `setGrid(prevGrid => makeRoute(prevGrid, cell[0], cell[1]));`. – MiniGunnR Jun 18 '21 at 21:12

0 Answers0