我知道这个问题已经在stackoverflow上被问了好几次,但即使尝试了几个小时,我也无法完成这项工作......
我已经使用 React.js 一年了,但我最近转向了 React 钩子和无状态组件,所以我对它们没有太多经验,所以如果解决方案很明显,请提前原谅我,因为我真的试图自己解决它之前问这里......
1. 我的代码在做什么:
我有一个简单的useEffect
钩子,我想在道具rank
发生变化时调用它。 在钩子中,我使用.then
调用toggleNodeByRank()
方法,并在执行方法后更新名为data
的状态。
2. 发生了什么:
目前,(几乎(一切正常,在第二个console.log('===StateUpdated===', chartData);
中,我可以看到我的状态具有正确的更新值。
唯一的问题是我的组件没有重新加载,如果我重复更新rank
道具的操作,我可以看到修改。
我看到一些答案说 deps(rank
这里(不好,我也试图在 deps 中添加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;
}
};
由于您正在就地更改原始节点元素而不是以不可变的方式更新它,因此setChartData
不会触发重新渲染,因为 react 会检查传递给状态更新程序的值是否实际上从以前的值更改,并且由于引用相同,它认为没有任何变化
根据 React 原则,您绝不能改变状态值,而是以不可变的方式更新它们。
如果可以以不可变的方式更新状态,请在 toggleNodeByRank 中执行此操作
但是,您仍然可以通过浅层克隆节点来解决,例如
const toggleNodeByRank = async (nodeArg, rank) => {
const node = {...nodeArg};
if (node && node.data) {
return node;
}
};
完成上述更改后,它将触发重新渲染,但您必须知道这不是最好的方法
您在理解承诺方面遇到问题,在您编写此 2 控制台时.log将输出相同的值(data) => setChartData(data)
因为 is 回调女巫将在切换节点ByRank完成后调用。 基本上你的代码是这样执行的:
1( console.log('===PreviousState===', chartData(;
2( 切换节点按排名(图表数据,排名(;在这里,您只需发送请求
3( console.log('===StateUpdate===', chartData(;
4( (数据(=> 设置图表数据(数据(
所以一切都很好,第二次运行组件更新时,您会看到更改chartData