React Hooks {useState, useEffect} v16.9 with examples
By: Melih Yumak
Tags: JavaScript, Web Development, React, Reactjs, Hooks

{ useEffect }

UseEffect is mostly used for data fetching, subscriptions or manual DOM changes in functional components. These operations called by effects because it is effecting other components.

There is three main lifecycle events we can use with useEffect.

componentDidMount

componentDidUpdate

componentWillUnmount

Lets use useState and useEffect together with counter example we made with useState.

import React, { useState, useEffect } from 'react';



function Example() {

const [count, setCount] = useState(0);



// Similar to componentDidMount and componentDidUpdate:

useEffect(() => {

// Update the document title using the browser API

document.title = `You clicked ${count} times`;

// Only re-run the effect if count changes

},[count]);



return (

<div>

<p>You clicked {count} times</p>

<button onClick={() => setCount(count + 1)}>

Click me

</button>

</div>

);

}

useEffect will be called when count is changed in functional component. Each time count has been changed it will update the document.title as number of count.

If it wanted to be written in class components componentDidMount and componentDidUpdate lifecycles needs to be added to class component like below.

class Example extends React.Component {

constructor(props) {

super(props);

this.state = {

count: 0

};

}



componentDidMount() {

document.title = `You clicked ${this.state.count} times`;

}



componentDidUpdate() {

document.title = `You clicked ${this.state.count} times`;

}



render() {

return (

<div>

<p>You clicked {this.state.count} times</p>

<button onClick={() => this.setState({ count: this.state.count + 1 })}>

Click me

</button>

</div>

);

}

}

That makes the same thing as we do with useEffect but we have to duplicate the code in componentDidMount and componentDidUpdate.

What does useEffect do?

By using useEffect component will listen changes after its rendered. Component will remember the passed function with useEffect.

UseEffect run after every render. It is manageable with second argument of useEffect. As you see example below we added second argument as count.

useEffect(() => {

document.title = `You clicked ${count} times`;

}, [count]); // Only re-run the effect if count changes

As we passed as second argument [count] will compare the count value from previous render. If it is not changed it will not be affected and useEffect function. React would skip that effect. Skipping effects increase performance of your components.

Effects with Cleanup

With useEffects we can add cleanup function very similar to componentWillUnmount. If there is some subscriptions from external data sources or intervals we want to remove after component removed from DOM.

If effects return a function that means it will used for cleanup. React will run it when its time to cleanup the effect.

Lets create an setInterval in with useEffect. Then return a function at the end of effect to clean interval. That means when our component removed from the DOM cleanup function will be executed and clear the created interval.

Since we didnt add any subscribers as second argument of useEffect that will only run when componentDidMount and componentWillUnmount.

If we wanted to use as class component we had to use as below

You can check it from codesandbox

Lets create another example for fetching data from bitcoin api.

That component will fetch bitcoin price every minute and print it out.

Here is the codesandbox example:

But if we want to make same thing with Effect

We used useEffect for componentDidMount, componentDidUpdate for refetch bitcoin price and returned clearInterval as componentWillUnmount.

You can check bitcoin price checking interval with useEffect from codesandbox. That is one of the useful use cases for clearing the interval when DOM element removed from the component otherwise it will cause memory leak and will try to fetch bitcoin prices while user looking another page.

We added the second argument to useEffect as [minutes] to execute useEffect only minutes has been changed in our

useEffect(() => { const interval = setInterval(() => { setMinutesState(seconds => seconds + 1); }, 60000); fetchBitcoinPrice(); return () => clearInterval(interval); }, [minutes]);

Conclusion

React team integrated very powerful things to functional components with {useState, useEffect} I highly suggest you to use it in your applications :)

You dont have to change all of your class based components to functional components in a day but it is good practice to have.

Thank you for reading this far. If you enjoyed this post, please share, comment, and press that 👏 a few times (up to 50 times). . . Maybe it will help someone.

Follow me on Medium or Github if you’re interested in more in-depth and informative write-ups like these in the future. 😀

Melih