javascript - React 组件中的递归函数调用
问题描述
我对以下(非常奇怪的)问题有疑问。
我有一个这样的父组件:
function ParentComponent() {
const [myParam, setMyParam] = React.useState(1);
useEffect(() => {
setTimeout(() => {
console.log('Setting myParam to 0...');
setMyParam(0);
}, 3000);
}, []);
return (
<div>
<ChildComponent myparam={myParam}></ChildComponent>
</div>
)
}
从这个父组件中,我将参数myParam
(默认值为 1)作为道具传递给子组件。
子组件如下所示:
function ChildComponent(props) {
const loop = () => {
if(props.myparam) { // DOES NOT DETECT PROP CHANGE PROPERLY!!!
setTimeout(() => loop(), 1000)
}
}
React.useEffect(() => {
if(props.myparam) {
loop();
}
}, [props.myparam])
return (
<div>
Loop demo
</div>
)
}
的初始值为myparam
1,因此loop
函数开始递归。
然后,父组件在 3 秒后更新道具,并且在子组件的钩子中正确检测到它,useEffect()
但是循环函数没有检测到道具更改并继续递归运行。
从我的角度来看,预期的行为是递归loop()
函数(myparam
loop()
if(props.myparam) { // DOES NOT DETECT PROP CHANGE PROPERLY!!!
setTimeout(() => loop(), 1000)
}
这种奇怪的行为有什么解释吗?
提前致谢!
解决方案
我在回答自己,因为我相信我找到了答案。
而不是props.myparam
在函数中用作条件loop()
:
if(props.myparam) { // DOES NOT DETECT PROP CHANGE PROPERLY!!!
setTimeout(() => loop(), 1000)
}
我使用局部变量作为标志:
if(runLoop) {
setTimeout(() => loop(), 1000)
}
在我有这个useEffect()
:ChildComponent
React.useEffect(() => {
if(props.myparam) {
runLoop = 1;
loop();
} else {
runLoop = 0;
}
return () => {
runLoop = 0; // this solves the issue
}
}, [props.myparam])
然后在useEffect()
中ChildComponent
我添加一个清理函数以设置runLoop
为 false - 脚本按预期工作。
所以我的结论是 React 基本上在每次渲染时都会实例化组件,并且之前渲染中的变量不会被更新(除非它们在清理时显式更新)。
推荐阅读
- wordpress - wordpress 自动将 -s 添加到 http
- python - 使用 pd.drop 将行拖放到另一个数据帧
- jquery - 动态添加item后,在owl-stage-outer外添加
- java - 使用 Esper java 的订购活动
- java - cdi-unit 测试因最近的 maven-failsafe-plugin 版本而失败
- javascript - MomentJS,UTC时间戳,是问题还是错误?,很少查询
- python - 无法使用 ProcessPoolExecutor 杀死子进程?
- angular - 是否可以在单个 Angular 客户端应用程序中使用 msal 和 Azure AD 访问和验证多个 API
- python - Discord.py 权限
- python - python-docx 仅更改标题左边距