reactjs - 反应清理功能不清理状态
问题描述
请各位高手解释一下,为什么在下面的代码中,属性的状态不会在useEffect清理函数中被清理?
我的组件:
export default function TestComp() {
let { id } = useParams();
const [value, setValue] = useState(null);
console.log('[TestComp] called...');
const cleanup = () => {
console.log('[TestComp] old value', value);
setValue(null);
};
useEffect(() => {
console.log('[TestComp] id changed: ', id);
console.log('[TestComp] value in useEffect', value);
setValue(id);
return () => {
cleanup();
}
}, [id]);
return (<React.Fragment>Test id: {id}</React.Fragment>)
}
控制台输出:
[TestComp] called... TestComp.js:8
[TestComp] old value satellites:MTP TestComp.js:11
[TestComp] id changed: satellites:MTP TestComp.js:16
[TestComp] value in useEffect satellites:FPGA TestComp.js:17
[TestComp] called... 2 TestComp.js:8
[TestComp] old value satellites:FPGA TestComp.js:11
[TestComp] id changed: satellites:FNE TestComp.js:16
[TestComp] value in useEffect satellites:MTP TestComp.js:17
[TestComp] called... TestComp.js:8
我希望,当 useEffect 将被调用 2. 时间时,该值将被清理并为null,但它仍保留旧值:
value in useEffect satellites:MTP TestComp.js:17
先感谢您。
解决方案
useEffect 的返回函数只是在应用下一个效果之前清理以前的效果。但是您的代码中的主要问题是
const cleanup = () => {
console.log('[TestComp] old value', value);
setValue(null); // This is not prefer way to use setValue here.
}
通常,在清理期间,我们取消订阅外部服务/订阅,但在这里您正在更改此处没有意义的状态,并立即通过运行的 useEffect setValue获取更新,并且在调用清理内部的setValue之后,这也是再次调用效果的原因,
在你的 useEffect 中添加 setTimeout 后检查你的代码。
`useEffect(() => {
console.log('[TestComp] id changed: ', id);
console.log('[TestComp]:Effect value in useEffect', value);
setValue(id);
return () => {
setTimeout(()=> cleanup(), 5000)
}
}, [id]);`
可能的解决方案 -
在上述情况下,您使用id,将此属性提升到父组件并将其作为属性传递给 TestComp 组件。
当效果运行时,整个组件会重新渲染,作用域会被破坏,但所有状态都保持在useState钩子的闭包内。
推荐阅读
- flutter - 如何在 Flutter 中创建具有固定列的水平滚动表格?
- git - 针对 master 与针对当前分支的 rebase?
- javascript - 电子邮件正文修改(Outlook 插件)
- java - 我们如何从firebase下载android studio中的文件(pdf),使其不会出现在手机的内部存储中?
- typescript - 带有 TypeScript 的 GatsbyJS:在布局中获取页面上下文?
- apache - 将 csv 文件加载到 Apache Phoenix 表并记录无效数据行
- mysql - ERROR 1265 (01000): 第 1 行的列 ' ' 的数据被截断
- python - _mysql_exceptions.ProgrammingError - 如何处理?
- kotlin - 如何在 Kotlin 中对查询参数进行 url 编码
- machine-learning - 神经网络无法识别基本输入模式