简体   繁体   English

使用当前道具对 useEffect 清理进行反应

[英]React useEffect cleanup with current props

I ran into a need of cleaning a useEffect when component is unmounted but with an access to the current props.当组件被卸载但可以访问当前道具时,我遇到了清理 useEffect 的需要。 Like componentWillUnmount can do by getting this.props.whatever就像 componentWillUnmount 可以通过获取 this.props.whatever 来做

Here is a small example: Click "set count" button 5 times and look at your console.这是一个小例子:单击“设置计数”按钮 5 次,然后查看您的控制台。 You'll see 0 from the console.log in component B, regardless "count" will be 5 https://codesandbox.io/embed/vibrant-feather-v9f6o您将在组件 B 的 console.log 中看到 0,无论“计数”为 5 https://codesandbox.io/embed/vibrant-feather-v9f6o

How to implement the behavior of getting current props in useEffect cleanup function (5 in my case)?如何实现在 useEffect 清理函数中获取当前道具的行为(在我的例子中为 5)?

UPDATE: Passing count to the dependencies of useEffect won't help because:更新:将计数传递给 useEffect 的依赖项将无济于事,因为:

  1. Cleanup will be invoked on every new count is passed to the props每次传递给 props 的新计数都会调用清理
  2. The last value will be 4 instead of the desired 5最后一个值将是 4 而不是所需的 5

Was referenced to this question from another one so will do a bit of grave digging for it since there is no accepted answer.从另一个问题中引用了这个问题,因此将对其进行一些挖掘,因为没有公认的答案。

The behaviour you want can never happen because B never renders with a count value of 5, component A will not render component B when count is 5 because it'll render unmounted instead of B, the last value B is rendered with will be 4.你想要的行为永远不会发生,因为 B 永远不会以 5 的计数值呈现,当计数为 5 时,组件 A 不会呈现组件 B,因为它将呈现卸载而不是B,呈现的最后一个值 B 将是 4。

If you want B to log the last value it had for count when it unmounts you can do the following:如果您希望 B 在卸载时记录它用于计数的最后一个值,您可以执行以下操作:

Note that effects executes after all components have rendered请注意,效果所有组件渲染执行

 const useIsMounted = () => { const isMounted = React.useRef(false); React.useEffect(() => { isMounted.current = true; return () => (isMounted.current = false); }, []); return isMounted; }; const B = ({ count }) => { const mounted = useIsMounted(); React.useEffect(() => { // eslint-disable-next-line react-hooks/exhaustive-deps return () => !mounted.current && console.log(count); }, [count, mounted]); return <div>{count}</div>; }; const A = () => { const [count, setCount] = React.useState(0); const handleClick = React.useCallback(() => { setCount(prevCount => prevCount + 1); }, []); if (count === 5) { //B will never be rendered with 5 return <div>Unmounted</div>; } return ( <React.Fragment> <B count={count} /> <button onClick={handleClick}>Set count</button> </React.Fragment> ); }; ReactDOM.render(<A />, document.getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

Since you passed empty array as dependency list for useEffect , your effect function only gets registered the first time.由于您将空数组作为useEffect依赖项列表useEffect ,您的效果函数仅在第一次注册。 At that time, the value of count was 0. And that is the value of count which gets attached to the function inside useEffect.那时,count 的值为 0。这就是附加到 useEffect 内部函数的 count 值。 If you want to get hold of the latest count value, you need your useEffect to run on every render.如果您想获得最新的计数值,您需要在每次渲染时运行 useEffect。 Remove the empty array dependency.删除空数组依赖项。

useEffect(() => {
  return () => console.log(count);
})

or use count as the dependency.或使用 count 作为依赖项。 That way, your effect function is created anew every time count changes and a new cleanup function is also created which has access to the latest count value.这样,每次计数更改时都会重新创建您的效果函数,并且还会创建一个可以访问最新计数值的新清理函数。

useEffect(() => {
  return () => console.log(count);
}, [count])

You need to track count in useEffect :您需要在useEffect跟踪count

import React, { useEffect } from "react";

const B = ({ count }) => {
  useEffect(() => {
    return () => console.log(count);
  }, [count]);

  return <div>{count}</div>;
};

export default B;

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

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