DEV Community

loading...

Component Will Unmount How to use componentWillUnmount with Functional Components in React

robmarshall profile image Robert Marshall Originally published at thoughtsandstuff.com on ・2 min read

Original article: https://thoughtsandstuff.com/componentwillunmount-functional-components-react

Functional components are far more efficient than class based components. There is also less code that is needed to be written to achieve the same goal.

However, I could not get my head around how functional components could implement the use of life-cycle events without needing to be changed to a class.

Turns out everything can be managed through useEffect.

I have used useEffect in the past to manage API calls, and what happened on a componentWillMount, but never componentWillUnmount. It turns out both are very similar!

How to manage componentWillMount with useEffect

To understand how we can use componentWillUnmount, first we need to look at how the component manages mounting with useEffect.

import React, { useEffect } from 'react';
const ComponentExample => () => {
   useEffect( () => {
      // Anything in here is fired on component mount.
   }, []);
}
Enter fullscreen mode Exit fullscreen mode

If we pass an empty array as the second argument, it tells useEffect to fire on component load. This is the only time it will fire.

With this in mind, how can we alter the code to work with componentWillUnmount? Turns out the solution is very simple.

How to manage componentWillUnmount with useEffect

If you add a return function inside the useEffect function, it is triggered when a component unmounts from the DOM. This looks like:

import React, { useEffect } from 'react';
const ComponentExample => () => {
    useEffect(() => {
        return () => {
            // Anything in here is fired on component unmount.
        }
    }, [])
}
Enter fullscreen mode Exit fullscreen mode

Combining both solutions

This means that you can use componentDidMount, and componentWillUnmount in the same useEffect function call. Dramatically reducing the amount of code needed to manage both life-cycle events. Like so:

import React, { useEffect } from 'react';
const ComponentExample => () => {
    useEffect(() => {
        // Anything in here is fired on component mount.
        return () => {
            // Anything in here is fired on component unmount.
        }
    }, [])
}
Enter fullscreen mode Exit fullscreen mode

Discussion (8)

pic
Editor guide
Collapse
arnabmunshi profile image
ARNAB MUNSHI

Hi, I need a help

  componentDidMount() {  
    this._subscribe();
  }

  componentWillUnmount() {
    this._unsubscribe();
  }

  async _subscribe() {
    const batteryLevel = await Battery.getBatteryLevelAsync();
    this.setState({ batteryLevel });
    this._subscription = Battery.addBatteryLevelListener(({ batteryLevel }) => {
      this.setState({ batteryLevel });
      console.log('batteryLevel changed!', batteryLevel);
    });
  }

  _unsubscribe() {
    this._subscription && this._subscription.remove();
    this._subscription = null;
  }

How to convert this in functional component ?
I have done something like this ...

  const getLevel = async () => {
    console.log("A: " + (await Battery.getBatteryLevelAsync()));

    let batteryLevel = Math.round((await Battery.getBatteryLevelAsync()) * 100);
    setLevel(batteryLevel);
    Battery.addBatteryLevelListener(({ batteryLevel }) => {
      batteryLevel = Math.round(batteryLevel * 100);
      setLevel(batteryLevel);

      console.log("B: " + batteryLevel);
    });
  };

  useEffect(() => {
    // Anything in here is fired on component mount.
    // componentDidMount
    getLevel();

    // componentWillUnmount
    return () => {
      // Anything in here is fired on component unmount.
    };
  }, []);

I am facing problem in

return function

Collapse
robmarshall profile image
Robert Marshall Author

If you don't need anything to fire on component unmount, you can remove the return.

  useEffect(() => {
    getLevel();
  }, []);
Collapse
amahecool profile image
amahecool • Edited

the returned function fires on component Re-render also. How to you check if its an unmount or just a re-render ?
Basically its just a clean up function which runs every time the useEffect is used (except the first time)

Collapse
gopeeey profile image
gopeeey

Thank you very much for this

Collapse
vladanpro profile image
Vladan Profirovic

import React, { useEffect } from 'react';
const ComponentExample => () => {
useEffect( () => {
// Anything in here is fired on component mount.
}, []);
}
hi srry this show me that is fired on component mount but not on will mount, so i try to find what is best solution to replace componentWillMount. Tnx.

Collapse
rahulbhadhoriya profile image
Rahul Bhadhoriya

Thanks very much

Collapse
seojeek profile image
Alex Vallejo

"Parsing error: Unexpected token, expected ","" is what i get when i try to return that

Collapse
pablobion profile image
Pablo Bion

Very cool!