【问题标题】:React state not changing using immer package使用 immer 包不改变反应状态
【发布时间】:2022-01-21 15:25:30
【问题描述】:

所以我非常困惑,基本上,当我点击它们时,瓷砖应该变成灰色,但事实并非如此。我很确定我这样做是正确的,除非我首先设置类型的方式缺少某些东西。更奇怪的是,有时当我通过扩展手动更改状态时,突然之间(仅针对我手动更改状态的单个图块),onClick 完美运行。感谢您的帮助,谢谢!

import React, { useEffect, useState } from 'react';
import produce from 'immer';
import { Node } from './astar';

export default function Grid(): JSX.Element {
  const [grid, setGrid] = useState<Node[][]>([]);
  const numCols = 50;

  useEffect(() => {
    let tempGrid: Node[][] = [];
    for (let i = 0; i < numCols; i++) {
      tempGrid.push([]);
    }

    for (let i = 0; i < tempGrid.length; i++) {
      for (let j = 0; j < tempGrid.length / 2; j++) {
        let node = new Node(i, j, false);
        tempGrid[i][j] = node;
      }
    }
    setGrid(tempGrid);
  }, []);

  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${numCols}, 20px)` }}>
      {grid.map((rows, i) => {
        return (
          <div key={i}>
            {rows.map((cols, j) => {
              return (
                <div
                  key={j}
                  onClick={() => {
                    const newGrid = produce(grid, (tempGrid) => {
                      tempGrid[i][j].isWall = !tempGrid[i][j].isWall;
                    });
                    setGrid(newGrid);
                    console.log(grid[i][j]);
                  }}
                  style={{ width: '20px', height: '20px', border: '1px solid black', backgroundColor: grid[i][j].isWall ? '#A9A9A9' : '#FFFFFF' }}
                ></div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}

节点类

class Node {
  x: number;
  y: number;
  isWall: boolean;

  constructor(x: number, y: number, isWall: boolean) {
    this.x = x;
    this.y = y;
    this.isWall = isWall;
  }
}

export { Node };

即使我点击它仍然不会改变状态。

【问题讨论】:

    标签: javascript reactjs typescript react-state immer.js


    【解决方案1】:

    您的Node 类需要用immerable 标记以使其与Immer 兼容:

    import {immerable} from "immer"
    
    class Node {
      [immerable] = true; //Add this line
    
      x: number;
      y: number;
      isWall: boolean;
    
      constructor(x: number, y: number, isWall: boolean) {
        this.x = x;
        this.y = y;
        this.isWall = isWall;
      }
    }
    
    export { Node };
    

    https://immerjs.github.io/immer/complex-objects

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 1970-01-01
      • 2019-07-25
      • 1970-01-01
      • 2017-11-19
      • 2020-01-05
      • 2020-05-18
      • 2020-09-30
      • 2019-04-11
      相关资源
      最近更新 更多