Javascript 反应效果不';状态更新后,无法重新加载我的组件
我知道这个问题已经在stackoverflow上被问了好几次了,但是我在几个小时内都没能解决这个问题 我在React.js上工作了一年,但最近我开始使用React钩子和无状态组件,所以我对它们没有太多经验,所以请原谅,如果解决方案很明显,因为在这里询问之前,我确实试图自己解决它 1。我的代码在做什么: 我有一个简单的Javascript 反应效果不';状态更新后,无法重新加载我的组件,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,我知道这个问题已经在stackoverflow上被问了好几次了,但是我在几个小时内都没能解决这个问题 我在React.js上工作了一年,但最近我开始使用React钩子和无状态组件,所以我对它们没有太多经验,所以请原谅,如果解决方案很明显,因为在这里询问之前,我确实试图自己解决它 1。我的代码在做什么: 我有一个简单的useffect钩子,我想在道具rank改变时调用它。 在钩子中,我使用调用toggleNodeByRank()方法。然后并在方法执行后更新名为data的状态 2。发生了什么: 目前
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正好有我想要的值,因此,我的代码可能还有另一个问题,因为如果状态已更新,组件不会重新加载事件。非常感谢您的回答@不过,正如我所说的,请尝试一下,看看是否可以以不变的方式更新节点。如果不是,那么只使用上面的解决方法:-)无论如何,很高兴能帮助:-)当然,我只需要研究一下这个概念,因为我对它不太了解,但至少目前我有一个临时解决方案!再次感谢;)