简体   繁体   English

Reacts useEffects 详尽的 deps 仅触发创建组件将卸载功能

[英]Reacts useEffects exhaustive deps only trigger to create component will unmount functionality

I am trying to implement a useEffect callback to dispatch an action before unmounting a component.我正在尝试实现一个 useEffect 回调以在卸载组件之前调度一个操作。 The point of this action is to store the last state of my component so I can resume from that state the next time this component is loaded.此操作的目的是存储组件的最后一个 state,以便下次加载此组件时可以从该 state 恢复。 I only want this callback to be triggered on unmount.我只希望在卸载时触发此回调。

When trying to use an empty dependency array for my useEffect, the 'exhaustive-deps' rule in reacts recommended 'eslint-plugin-react-hooks' demands I include the value I am trying to persist.当尝试为我的 useEffect 使用空依赖项数组时,“exhaustive-deps”规则会响应推荐的“eslint-plugin-react-hooks”要求,我包含了我试图坚持的值。 This results in the effect and therefore action being triggered every time I store state.这导致每次我存储 state 时都会触发效果和动作。

Is there a better way to handle this situation then disabling eslint for this line?有没有更好的方法来处理这种情况,然后禁用这条线的 eslint?

Here is what I want:这是我想要的:

...
const [value, setValue] = useState('');

useEffect(() => {
    return () => {
        storeValueAction(value);
    };
}, []);
...

The way eslint-plugin-react-hooks wants it and results in the action being dispatched on every state change: eslint-plugin-react-hooks 想要它并导致在每个 state 更改上调度操作的方式:

...
const [value, setValue] = useState('');

useEffect(() => {
    return () => {
        storeValueAction(value);
    };
}, [value, storeValueAction]);
...

Is there something other than useEffect I should be using for this?除了 useEffect 我还应该使用什么?

Even if you implement it in the current manner and disable the eslint rule, the expected result won't be correct since the state value dispatched on unmount will be the state value during the initial mount due to closure.即使您以当前方式实现它并禁用 eslint 规则,预期结果也不会正确,因为卸载时调度的 state 值将是初始挂载期间的 state 值,因为关闭。

For such a case, you can make use of useRef along with useEffect to achieve a desired result.对于这种情况,您可以使用 useRef 和 useEffect 来实现所需的结果。 Once you do that you can safely disable the eslint rule being assured that you code won't result in an unexpected behaviour一旦你这样做了,你可以安全地禁用 eslint 规则,确保你的代码不会导致意外的行为

const [value, setValue] = useState('');
const valueRef = useRef(value);

useEffect(() => {
   valueRef.current = value;
}, [value]);

useEffect(() => {
    return () => {
        storeValueAction(valueRef.current);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM