专家们,请解释一下,为什么在下面的代码中,属性的状态不会在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我希望,当第2次调用useEffect时,值将被清除并为空,但它仍然保留旧值:
value in useEffect satellites:MTP TestComp.js:17提前谢谢你。
发布于 2019-12-10 11:25:21
从useEffect返回函数只需要在应用下一个效果之前清除前面的效果。但是代码中的主要问题是
const cleanup = () => {
console.log('[TestComp] old value', value);
setValue(null); // This is not prefer way to use setValue here.
}通常情况下,在清理过程中,我们取消了外部服务/订阅,但这里您更改的状态在这里没有意义,并立即得到运行的useEffect setValue的更新,以及在调用setValue之后立即更新,这也是再次调用效果的原因。
在setTimeout中添加useEffect后,检查代码。
`useEffect(() => {
console.log('[TestComp] id changed: ', id);
console.log('[TestComp]:Effect value in useEffect', value);
setValue(id);
return () => {
setTimeout(()=> cleanup(), 5000)
}
}, [id]);`可能的解决办法-
发布于 2019-12-10 09:44:39
您可能需要添加另一个useEffect,因为在当前情况下,cleanup函数将只在卸载上运行,这对当前逻辑非常无用。
export default function TestComp() {
let { id } = useParams();
const [value, setValue] = useState(null);
console.log('[TestComp] called...');
useEffect(() => {
console.log('[TestComp] id changed: ', id);
console.log('[TestComp] value in useEffect', value);
setValue(id);
/* v Useless cleanup because the component unmounts anyway,
the `value` state will be cleaned automatically.
return () => {
cleanup();
}
*/
}, [id]);
// ^ Firstly, the `value` changed on id change
// v Secondly, the `value` will be reset on `value` change
useEffect(() => {
console.log('[TestComp] old value', value);
setValue(null);
}, [value]);
return <>Test id: {id}</>;
}发布于 2019-12-10 08:59:14
我认为这是事情发生的顺序的问题。
useEffect将在调用闭包时,即当调用TestComp函数时,作为闭包的一部分来“捕获”值。当id更改响应时,将调度对清除函数的调用,然后对效果进行调用。但是,直到调用了新的效果函数之后,才会再次调用TestComp。
您可以在日志中看到这一点,因为清除函数中的每个old value都紧跟在id changed之后。
而且,由于新的效果函数从调用TestComp时‘捕获’值,它将不会看到由清理函数设置的值。
另外,请注意,至少从测试中我看到了React抱怨value和cleanup不存在于useEffect的依赖项中。
https://stackoverflow.com/questions/59262857
复制相似问题