状态更新后,React useEffect不会重新加载组件

时间:2020-05-28 09:59:09

标签: javascript reactjs react-hooks use-effect

我知道这个问题已经在stackoverflow上问过几次了,但是即使经过几个小时的尝试,我也无法使它工作……

我已经使用React.js一年了,但是最近我转向了React钩子和无状态组件,因此我对它们没有太多的经验,因此如果解决方案显而易见,请提前为我辩解,因为我确实尝试解决它是我自己问的,然后在这里...

1。我的代码在做什么:

我有一个简单的useEffect钩子,当道具rank更改时,我想调用它。 在挂钩中,我正在使用toggleNodeByRank()调用.then方法,并在执行该方法后更新名为data的状态。

2。发生了什么事:

目前,(几乎)一切正常,在第二个console.log('===StateUpdated===', chartData);中,我可以看到我的状态具有正确的更新值。

唯一的问题是我的组件不会重新加载,并且如果我重复更新rank道具的操作,我就能看到所做的修改。

我已经看到一些答案,说部门(rank)不好,我也尝试在部门(chartData)中添加[rank, chartData],但是问题仍然存在。一样...

也许有人可以帮我这个忙吗?

useEffect(() => 
  console.log('===PreviousState===', chartData);

  toggleNodeByRank(chartData, rank).then((data) => setChartData(data));

  console.log('===StateUpdated===', chartData);

}, [rank]);

3。编辑

这里是toggleNodeByRank()函数,因为这是我公司的代码,所以我不想分享太多,希望对您有所帮助。

  const toggleNodeByRank = async (node, rank) => {
    if (node && node.data) {
      // await update node.children depending on node.rank
      // - If I want to toggle the node :
      // I am saving the node.children in a state object (key = node.id, 
      // value = node.children) and I reset the node.children value to [ ]
      // - If I don't want to toggle the node :
      // I don't do anything and juste render
      // update another state to save the node.children data if needed.
      return node;
    }
  };

2 个答案:

答案 0 :(得分:2)

由于您是对原始节点元素进行了变异,而不是以不可变的方式对其进行更新,因此setChartData不会触发重新渲染,因为反应会检查传递给状态更新程序的值是否与先前的值实际发生了更改是否有价值,并且由于引用相同,因此认为没有任何改变

根据React原则,您绝不能突变状态值,而不能以不变的方式更新它们。

如果您有可能以不变的方式更新状态,请在toggleNodeByRank中进行操作

但是您仍然可以通过像这样的浅层克隆来解决该问题

const toggleNodeByRank = async (nodeArg, rank) => {
    const node = {...nodeArg};
    if (node && node.data) {
      return node;
    }
  };

完成上述更改后,它会触发重新渲染,但您必须知道这不是最好的方法

答案 1 :(得分:0)

您在理解诺言方面有问题,在您的代码中这2 console.log将输出相同的值,因为(data) => setChartData(data)是回调巫婆,在toggleNodeByRank完成后将被调用。 基本上,您的代码以这种方式执行:

1)console.log('=== PreviousState ===',chartData);

2)toggleNodeByRank(chartData,rank); //在这里您只是发送请求

3)console.log('=== StateUpdated ===',chartData);

4)(数据)=> setChartData(数据)

所以一切都很好,第二次当您运行组件更新时,您看到更改了chartData