Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应效果不';状态更新后,无法重新加载我的组件_Javascript_Reactjs_React Hooks_Use Effect - Fatal编程技术网

Javascript 反应效果不';状态更新后,无法重新加载我的组件

Javascript 反应效果不';状态更新后,无法重新加载我的组件,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,我知道这个问题已经在stackoverflow上被问了好几次了,但是我在几个小时内都没能解决这个问题 我在React.js上工作了一年,但最近我开始使用React钩子和无状态组件,所以我对它们没有太多经验,所以请原谅,如果解决方案很明显,因为在这里询问之前,我确实试图自己解决它 1。我的代码在做什么: 我有一个简单的useffect钩子,我想在道具rank改变时调用它。 在钩子中,我使用调用toggleNodeByRank()方法。然后并在方法执行后更新名为data的状态 2。发生了什么: 目前

我知道这个问题已经在stackoverflow上被问了好几次了,但是我在几个小时内都没能解决这个问题

我在React.js上工作了一年,但最近我开始使用React钩子和无状态组件,所以我对它们没有太多经验,所以请原谅,如果解决方案很明显,因为在这里询问之前,我确实试图自己解决它

1。我的代码在做什么:

我有一个简单的
useffect
钩子,我想在道具
rank
改变时调用它。 在钩子中,我使用
调用
toggleNodeByRank()
方法。然后
并在方法执行后更新名为
data
的状态

2。发生了什么:

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

唯一的问题是我的组件没有重新加载,如果我重复更新
rank
道具的操作,我可以看到修改

我看到一些答案说DEP(
rank
此处)不好,我也尝试在DEP中添加
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 console.log将输出相同的值,因为
(数据)=>setChartData(数据)
是回调,在toggleNodeByRank完成后将调用该回调。 基本上,您的代码是这样执行的:

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

2) toggleNodeByRank(图表数据,排名)//在这里,您只需发送请求

3) log('==StateUpdated==',chartData)

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


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

,因为您是在原地修改原始节点元素,而不是以不变的方式更新它,
setChartData
不会触发重新渲染,因为react会检查传递给状态更新程序的值是否与以前的值发生了更改,并且由于引用相同,它认为没有任何更改

根据React原则,决不能改变状态值,而要以不变的方式更新它们

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

但是,您仍然可以通过浅克隆节点来解决此问题,如

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

执行上述更改后,将触发重新渲染,但您必须知道这不是最佳方式

请在useEffect依赖项中使用async Wait并传递setChartData。喜欢<代码>常数数据=等待toggleNodeByRank(图表数据,等级);setChartData(data)
@ArunkarthiMani您不能在
useEffect
中使用异步,除非您使用IIFE,使用
async/await
chartData
仍然是相同的值,由于它从相同的渲染周期获得相同的作用域,我只能通过在我的
useffect
方法中创建一个自定义函数来使用useffect,如下所示:
const data=async()=>{const tmp=await toggleNodeByRank(chartData,rank);返回tmp;}问题是,当我
console.log
异步函数的结果时,我得到:
Promise{}
,我不知道如何解决这个问题…请同时显示其他代码部分。看看为什么不重新呈现组件。知道toggleNodeByRank做了什么很重要非常感谢你的回答,但是实际上(如果我很理解你的观点的话)我的第二个console.log正好有我想要的值,因此,我的代码可能还有另一个问题,因为如果状态已更新,组件不会重新加载事件。非常感谢您的回答@不过,正如我所说的,请尝试一下,看看是否可以以不变的方式更新节点。如果不是,那么只使用上面的解决方法:-)无论如何,很高兴能帮助:-)当然,我只需要研究一下这个概念,因为我对它不太了解,但至少目前我有一个临时解决方案!再次感谢;)