DEV Community

loading...

React Hooks Part 1 - Understanding useState and useEffect Hooks

thenerdydev profile image The Nerdy Dev ・6 min read

Hey everyone 👋🏻,

In this article, let us discuss about React Hooks. So this is first part of the React Hooks series where we will cover 2 React Hooks in great depth - the useState and the useEffect hooks. So let us first understand what actually are these React Hooks.

What are React Hooks ?

React Hooks are typically JavaScript functions that let you HOOK into React State and Lifecycle methods provided by React. They let us use state and other React features without having us to write a class. React ships with a couple of built-in hooks like useState, useEffect, useContext, useReducer and more and you can even create your own custom hook which we will see in a separate article.

In this article, we will go over the following React Hooks:

  1. useState
  2. useEffect

But before that let us understand the rules that we as developers should abide by while working with React Hooks.

RULES OF HOOKS :

  1. Only call React Hooks in React functions. That means in react component functions. You can also call React Hooks in custom hooks that you create.
  2. Only call React Hooks at the top level - Don't call them in nested functions. Don't call them in any block statements.

With that out of the way, let us understand each of the above 4 hooks one by one :

useState

If you want to want to use state in a functional component, then we can leverage the useState React Hook for that. It is quite easy to use the useState React Hook. The very first step is to import the useState Hook from React at the top of your component file.

Alt Text

Now the SYNTAX of the useState function is something like this :

Alt Text

So here we are using array destructuring to pull out the two arguments that useState spits. First it gives us the current state value and the second one is the state updating function using which we can update our state.

Let us understand the useState hook with the help of the below example :

Alt Text

In the above example, all we have is a ThingsList Component where we have a form using which we can add a new thing to our list of things. So here we have defined two pieces of state - one is the things where we manage our list of things and we have given it an initial value to [], second we have the thing piece of state that is used to collect the generated state from the form. So in the above example, the form element generates some piece of state and it is this state that we want to commit to our component states so that we always have the latest state snapshots.
Also after form submission, we reset our form state back to empty quotes and our new thing is now a part of the things list.

useEffect

To understand the useEffect React Hook, we first need to understand about the Side Effects.

What are Side Effects ?

From our knowledge of React, we know that our React App has one main role : render the UI and react to user input to re-render the UI when it is needed.
So React evaluates and renders JSX, manages state and props, re-evaluates the component upon changes in state and props. This is all possible because of the reactivity system of React and the features that React ships with.

Side Effects

Side Effects are anything else that might be happening in your application. It could be some HTTP request that you make, storing something in the localStorage, setting and managing timers.
Now the main thing to emphasize here is that these tasks (which we termed as side effects) must happen outside of the normal component evaluation and render cycle and the reason for that is that these side effects might block or delay the rendering process.

So next let us see how we can handle these side effects using the useEffect Hook.
So the very first step is to import the useEffect Hook at the top of your component file.

Alt Text

The useEffect Hook is simply another built in hook. Let us see the basic structure of a useEffect hook

Alt Text

The first argument to useEffect is a function that should be executed AFTER every component evaluation if there is a change in the specified list of dependencies

The second argument is the list of dependencies which are the specific dependencies of this effect - the function only runs if there is a change in these dependencies. So whenever such a dependency changes, the function that gets passed as the first argument to useEffect Hook will re-run. Therefore in that first function you can put any side effect code and that code will then only execute when there is a change in the specified dependencies and not when the component re-renders.

You should add everything that you use in the effect function as a dependency i.e all the state variables and the functions you use in there.

That is of course correct, but there are a few exceptions that you should be aware of :

  1. DON'T add state updating functions to the list of dependencies because ultimately these are functions that will never change.

  2. DON'T add built-in APIs or functions like fetch, localStorage, browser APIs because they by any means are not related to the React Component Render Cycle and they also never change. So it does not make sense to put them into the list of dependencies if they are not bound to change.

  3. DON'T add variables or functions that you might have defined outside of your components because even if they change they are not going to cause a re-evaluation of your components.

Let us see a very simple example to understand this :

Alt Text

In this example :

isTimerActive is added as a dependency because it's in the component state that may change when the component changes (e.g because the state was updated)

duration is added as a dependency because we are receiving it as prop on our Timer component - so it may change if a parent component changes that value (causing this Timer component to re-render as well)

setIsTimerActive is NOT added as a dependency because it is a state updating function. I just mentioned a while back that state updating functions don't have to be added since it is guaranteed that these functions will never change.

aTimer is NOT added as a dependency for the simple reason that it is defined outside the component and hence changing it (no matter where) wouldn't cause the component re-evaluation.

setTimeout is NOT added as a dependency because it's a built-in Browser API -it is independent from React and your components and it does not change as well.

useEffect for cleanup

Sometimes we may need an effect for performing cleanup tasks. So what we do in this case is that we return a cleanup function which React ultimately executes to perform the cleanup task (see the structure of useEffect shown above).

Now before the execution of the useEffect function, except for the very first time when it runs, this cleanup will run. In addition, the cleanup function will also get executed when the component you're specifying the effect in unmounts from the DOM.
So the cleanup function would run before every new side effect function execution and before the component is removed.

So this is it for the very first part of React Hooks. In the next article, we will learn about other React Hooks. So stay tuned !

If you are looking to learn Web Development, I have curated a FREE course for you on my YouTube Channel, check the below article :

If you have spare 2 hours, then utilize them by creating these 10 JavaScript Projects in under 2 Hours

👉🏻 Follow me on Twitter : https://twitter.com/The_Nerdy_Dev

👉🏻 Check out my YouTube Channel : https://youtube.com/thenerdydev

Discussion (1)

Collapse
dev_emmy profile image
Forem Open with the Forem app