【问题标题】:Weird Reactjs state behaviour when accessing it from outside render从外部渲染访问它时奇怪的 Reactjs 状态行为
【发布时间】:2021-09-07 00:45:45
【问题描述】:

我正在制作一个简单的绘图示例,用户可以通过单击和拖动来绘制直线。

我想要实现的功能之一是能够通过双击删除一行,我遇到的问题是从状态数组中删除这样的行,我有一个基本的 example here

不幸的是,当我尝试 console.log() 状态数组 allPaths 时,应用程序会冻结,但在我的本地设置中不会发生这种情况。

例如:

  1. 用户画了 4 条线
  2. 双击控制台日志的第一行,其 ID 和空状态数组[]
  3. 双击第四行,日志显示行 ID 和长度为 3 的状态数组,其中包含前 3 行,但它不显示整个数组...?

在我的本地设置中,当我在双击时console.log(allPaths) 在创建特定行之前获得allPaths 状态,它不会显示所有条目,但是当我在渲染方法中log 时它会显示所有条目都很好。

我不知道我做错了什么......

【问题讨论】:

  • JSON.stringify 登录useEffect 而不是直接登录allPaths——在修复我看到的一个冻结的沙箱中。
  • @DaveNewton,效果更好,但它不能解决问题,数组allPaths 正在返回在我试图删除的特定行之前创建的元素,即使allPaths 是状态数组
  • 没说是这样 ;) 只是循环时的一般调试提示。

标签: javascript reactjs state


【解决方案1】:

在每个渲染周期中创建新层,而不是使用 ref 来跟踪层,防止创建新层。

进行以下更改:

  const markersLayer = useRef(new Paper.Group());
  const floorplanLayer = useRef(new Paper.Group());
  const trashAllPaths = () => {
    setAllPaths([]);
  };

  const removePath = (id) => {
    setAllPaths((paths) => paths.filter((p) => p.id !== id));
  };

  const savePath = (path) => {
    setAllPaths((paths) => [...paths, path]);
  };
  markersLayer.current.addChildren([ghostLine]);
  useEffect(() => {
    floorplanLayer.current.removeChildren();
    floorplanLayer.current.addChildren(allPaths);
  }, [allPaths, floorplanLayer]);

【讨论】:

    【解决方案2】:

    它冻结的原因是因为Path 是一个重物。正如我所看到的,您有allPaths,它是一个包含属性id 的对象数组。我还可以看到,在路径上双击可以获得路径 ID。

    所以,为了删除一行,我认为这会起作用:

    const removeLine = (id) => {
      const allPathsCopy = [...allPaths]
      setAllPaths(allPathsCopy.filter(path => path.id !== id));
    }
    

    【讨论】:

    • 谢谢你,Sagi,我以前试过,不幸的是它不起作用,它应该但它没有。原因是当您触发该方法时,它会返回一个不同的 allPaths 数组内容,我不明白为什么?它在创建该行时返回数组的状态,因此如果您绘制 4 条线并尝试删除第三条,allPaths 数组将返回在第三条之前创建的前 2 条路径,希望这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2015-03-10
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    相关资源
    最近更新 更多