1

i use this code in my react project when change data1 with usestate , i see data1 is change to 1 but when unmount component data1 is default value 0 . whats wrong? code is:

useEffect( () => console.log( ["mount",data1] ), [] );
useEffect( () => console.log( ["will update",data1] ) );
useEffect( () => () => console.log( ["unmount",data1] ), [] );

log when mount and change is:

["mount", "0"]
["will update", "0"]
["will update", "2"]
["unmount", "0"]
Mehran Motiee
  • 3,547
  • 1
  • 13
  • 16
  • 1
    Could you update your code snippet with code related to state variable `data1`? Or, even better, share the whole component. – Pa Ye Feb 28 '19 at 13:35
  • These were helpful for me: https://stackoverflow.com/questions/57023074/why-is-the-cleanup-function-from-useeffect-called-on-every-render https://stackoverflow.com/questions/55020041/react-hooks-useeffect-cleanup-for-only-componentwillunmount – frederj Jul 14 '20 at 18:51

2 Answers2

4

When you define your effect like

useEffect( () => () => console.log( ["unmount",data1] ), [] );

You essentially tell it to run on initial render and hence the data1 that the callback points to is the initial value that it inherited from the closure and is never updated since the function is no longer initialised

If at all, for any reason you want the data1 to be accessible in useEffect you must pass it as the second argument to useEffect

useEffect( () => () => console.log( ["unmount",data1] ), [data1] );

In such a case the effect will be cleaned up any change of data1

You could also make use of useRef to store the data and access it in unmount.

function App() {
  const [data1, setData1] = useState(0);
  const refAttr = useRef();
  useEffect(
    () => () => {
      console.log("unmount", refAttr.current);
    },
    []
  );
  useEffect(() => {
    setInterval(() => {
      setData1(data1 => {
        refAttr.current = data1 + 1;
        return data1 + 1;
      });
    }, 1000);
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Working demo

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • i need unmount mod.when add data1 at end , useEffect run when data1 change not when unmount. how can get data1 just when unmount with hooks? – Mehran Motiee Feb 28 '19 at 12:57
  • 1
    If you add data1 at the end, useEffect will run the callback on data1 change but will also run it on unmount. The other way is to make use of `useRef` to store data in it and then get data from it in useEffect – Shubham Khatri Feb 28 '19 at 13:09
  • Updated the answer with a solution using ref – Shubham Khatri Feb 28 '19 at 13:22
2

i finaly use this function for get last data when unmount

thanks from "nima arefi" for write it

const useTaskBeforeUnmount = ( calback, ...data ) => {
        const mounted = React.useRef( null );

        React.useEffect( () => {
            mounted.current = true;
            return () => {
                mounted.current = false;
            };
        }, [] );

        React.useEffect(
            () => () => {
                if ( !mounted.current ) {
                    calback( { ...data } );
                }
            },
            [ calback, ...data ],
        );
    };

then use it in my component like this

useTaskBeforeUnmount( console.log, data1, data2, data3 );
Mehran Motiee
  • 3,547
  • 1
  • 13
  • 16