Cleanup memory leaks on an Unmounted Component in React Hooks

前端 未结 4 1377
再見小時候
再見小時候 2020-12-13 09:06

I\'m new using React, so this might be really simple to achieve but I can\'t figure it out by myself even though I\'ve done some research. Forgive me if this is too dumb.

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-13 10:10

    You could use the 'cancelActiveVisits' method of Inertia to cancel the active visit in useEffect cleanup hook.

    So with this call the active visit will be cancelled and state will not get updated.

    useEffect(() => {
        return () => {
            Inertia.cancelActiveVisits(); //To cancel the active visit.
        }
    }, []);
    
    

    if the Inertia request get cancelled then it will return an empty response so you have to add an extra check to handle the empty response. Add add catch block as well to handle any potential errors.

     function handleSubmit(e) {
        e.preventDefault();
        setLoading(true);
        Inertia.post(window.route('login.attempt'), values)
          .then(data => {
             if(data) {
                setLoading(false);
             }
          })
          .catch( error => {
             console.log(error);
          });
      }
    

    Alternate way (workaround)

    You Could use useRef to hold the status of the component and based on this you can update the state.

    Problem:

    The warring is showing because the handleSubmit is trying to update the state of the component even though component has unmounted form the dom.

    Solution:

    Set a flag to hold the status of the component, if the component is mounted then the flag value will be true and if the component is unmounted the flag value will be false. So based on this we can update the state. For flag status we can use useRef to hold a reference.

    useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component. In useEffect return a function which will set the status of the component, if it is unmounted.

    And then in useEffect in the cleanup function we can set the flag to false.

    useEffecr cleanup function

    The useEffect hook allows using a cleanup function. Anytime the effect is no longer valid, for example when a component using that effect is unmounting, this function is called to clean everything up. In our case, we can set the flag to false.

    Example:

    let _componentStatus.current =  useRef(true);
    useEffect(() => {
        return () => {
            _componentStatus.current = false;
        }
    }, []);
    

    And in handleSubmit we can check if the component is mounted or not and update the state based on this.

    function handleSubmit(e) {
        e.preventDefault();
        setLoading(true);
        Inertia.post(window.route('login.attempt'), values)
            .then(() => {
                if (_componentStatus.current) {
                    setLoading(false);
                } else {
                    _componentStatus = null;
                }
            })
    }
    
    

    In else set the _componentStatus to null to avoid any memory leaks.

提交回复
热议问题