useState and useEffect explained

They are fun and concise

Manoj Singh Negi
recraftrelic
5 min readApr 29, 2019

--

Canvas & Pixabay

UPDATE : I have made a video on this topic you can watch it here https://youtu.be/ek-62uxioNE

React is a great library to write reusable UI. The problem React faced for a long time is reusing logic. Developers introduced techniques like HOC and Render Props to overcome this, but both of the techniques easily go off the rails and components become very complex ( hard to reason about ) if we use these techniques heavily.

React introduced Hooks to overcome this obstacle. React Hooks are a great way to reuse logic throughout your project. Not only they provide you a way to reuse logic in my opinion, but they also help in cleaning the syntax by making your code look more like simple functions.

The most popular and commonly used hooks are useState and useEffect

useState

The state can now be used inside functional components that is made possible by the useState hook. Let’s have a look at how we can use useState

let [item, setItem] = useState('default value')

Let’s break things down.

we call the useState function and pass a default value as an argument. The useState function returns an array which contains two items item and setItem

The item is the variable which will store our value and setItem is an updater function which will be responsible to update the item simple as that.

We should also consider the default value passed to useState will be the initial value of the item. In our case, it’s a string but it can be of any datatype.

For updating the value in the state you just have to do something like this.

<button onClick={() => setItem('Macbook Pro')}>
Add Macbook Pro
</button>

You should also note that setItem function always overwrites the value rather than merging the new value to old value. For e.g.

let [person, updatePerson] = useState({ name: 'Manoj', age: 21 })return (
<button onClick={() => updatePerson({ age: 22 })}>Update age</button>
)
// in the next render the person will be
{ age: 22 }
// rather than
{ name: 'Manoj', age: 21 }

For solving this useState also provide a very simple solution. We can also pass a function rather than a value to updatePerson and in that function, our previous state will be available.

<button onClick={prevState => updatePerson({ ...prevState, age: 22 })}>Update age</button>

Once we have the previous state we can merge the new and previous state to avoid overwriting the previous state with the new one.

useEffect

useEffect is an interesting one. It removes the need for componentDidMount , componentDidUpdate and componentWillUnmount because it handles the use case of all of these life cycle methods. Let’s have a look

useEffect(() => {
// hit an API
}, [])

This useEffect will work like a componentDidMount

Let’s break this down.

useEffect takes a function which can contain any kind of operation including side effects. Any kind of side effect is not allowed inside the render method (or inside the function in case of a functional component). So any kind of side effect should be used inside useEffect

useEffect also takes a second argument as an array [], in this array you can pass variables. When any of this variable updates it will cause the useEffect to run again, because we passed an empty array our useEffect will only run once throughout the life of our component.

If we didn’t pass the second argument something like this

useEffect(() => {
// hit an API
})

This will cause useEffect to run after every render, just like componentDidUpdate but I doubt you would be using this a lot because most of the time we don’t want the side effects to run after every render.

Another use case for useEffect will be something like this

let [item, setItem] = useState('default value')useEffect(() => {
// hit an API
}, [item])
return (
<button onClick={() => setItem('Macbook Pro')}>
Add Macbook Pro
</button>
)

Alright, so what is happening here?

We have a variable name item in our state. When we click the Add Macbook Pro our item value will be updated to Macbook Pro and also our useEffect will get triggered because we passed the item to useEffect and because of that whenever we update the value of item our useEffect will run.

Last but not least let’s have a look at how we should implement componentWillUnmount using useEffect

Most of the use case of componentWillUnmount is for cleaning of event listeners or subscriptions ( like socket.io events) let’s see how we can implement that.

useEffect(() => {
window.addEventListener('click', () => console.log('capture clicks'))
return () => {
window.removeEventListener('click', () => console.log('clean clicks listener'))
}
}, [])

Whatever function we return from the useEffect will be treated as componentWillUnmount and will run either when the useEffect runs again or when the component is about to leave the UI.

By combining all of the life cycles methods into one hook we can easily group the same kind of functionality together rather than only one useEffect we can also use as many useEffect we want to add. That means you can subscribe to an event and unsubscribe from it inside one useEffect and hit APIs in another useEffect

The order of hooks

A very important thing we have to understand is that we can’t change the order or numbers of the hooks in each render. It must be the same in every render. That means we can’t use conditional hooks. For e.g

if (item) {
useEffect(() => {}) // you can't do this
}
or this items.forEach(() => useEffect(() => {}))// because if the length of items changes the useEffect count will not be same in the next render.

keep sharing 😃 and clapping 👏

Here are more articles for you.

Hi, My name is Manoj Singh Negi. I am a Javascript Developer and writer follow me at Twitter or Medium.

I am available to give a public talk or for a meetup hit me up at justanothermanoj@gmail.com if you want to meet me.

Really loved this article ?

Please subscribe to my blog. You will receive articles like this one directly in your Inbox frequently.

Peace.

--

--

Manoj Singh Negi
recraftrelic

I write about Javascript http://eepurl.com/co0DYj. Solving people problems using code. Javascript developer, Writer.