how to use fresh state inside the useeffect, but execute cleanup on unmount only

Viewed 234

AFAIK, in the React Function Component, one has to use useEffect for componentWillUnmount functionality like below:

useEffect(()=>{
  return console.log("component unmounting");
},[])

I am making a form page, and want to submit the progress when the user exits the page. So I am thinking of submitting inside the cleanup.

But if I don't put the formData state into the dependency array, the state will be stale during the cleanup.
And if I do put formData into the dependency array, the cleanup will run every time there is a change in formData.

How can I keep the state fresh, but run the cleanup only in the 'real unmount'?

const [formData, setFormData] = useState({
  input1: 'input1 default',
  input2: 'input2 default',
}); // track the form data


useEffect(()=>{
  return () => {
    axios.post(myFormSubmitURL, formData);
  }
}, []); // this will submit the stale data

useEffect(()=>{
  return () => {
    axios.post(myFormSubmitURL, formData);
  }
}, [formData]); // this will submit the data every time it changes
1 Answers

You can use a react ref and additional effect to store a cache of your form state for use when the component unmounts.

const formDataRef = useRef();
const [formData, setFormData] = useState({
  input1: 'input1 default',
  input2: 'input2 default',
}); // track the form data


useEffect(()=>{
  return () => {
    axios.post(myFormSubmitURL, formDataRef.current); // <-- access current value
  }
}, []);

useEffect(()=>{
  formDataRef.current = { ...formData }; // <-- cache form updated data
}, [formData]);
Related