Understanding React `useState` and `useEffect` hooks
Tags: react, tutorial, beginners, javascript
Published: 2020-11-27 12:12:56

---
title: Understanding React `useState` and `useEffect` hooks
published: true
description: Let's learn some React hooks today
tags: react, tutorial, beginners, javascript
canonical_url: https://sebhastian.com/react-usestate-useeffect-hooks/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/mqlknkmf02nep298p85u.jpg
---

React hooks are JavaScript functions that you can import from React package in order to add features to your components. Hooks are available only for function-based components, so they can't be used inside a class component.

React provides you with 10 hooks function, but only 2 of these hooks are going to be used very frequently when you write function components. They are `useState` and `useEffect` hooks. Let's learn about `useState` first.

The `useState` hook is a function that takes one argument, which is the initial state, and it returns two values: the current state and a function that can be used to update the state. Here's the hook in action:

```jsx
import React, { useState } from 'react'

function UserComponent() {
  const [name, setName] = useState('John')
}
```

Notice the use of square brackets when state variable is declared. This is the ES6 [array destructuring syntax](https://sebhastian.com/react-destructuring/), and it means we’re assigning the first element of the array returned by useState to `name` and the second element to `setName` variable.

So this means we have a state named `name` and we can update it by calling on `setName()` function. Let’s use it on the return statement:

```jsx
import React, { useState } from 'react'

function UserComponent() {
  const [name, setName] = useState('John')

  return <h1> Hello World! My name is {name} </h1>
}
```

Since function components don't have the `setState()` function, you need to use the `setName()` function to update it. Here's how you change the name from "John" to "Luke":

```jsx
import React, { useState } from 'react'

function UserComponent() {
  const [name, setName] = useState('John')

  if(name === "John"){
    setName("Luke")
  }

  return <h1> Hello World! My name is {name} </h1>
}
```

When you have multiple states, you can call the `useState` hook as many times as you need. The hook receives all valid JavaScript data types such as string, number, boolean, array, and object:

```jsx
import React, { useState } from 'react'

function UserComponent() {
  const [name, setName] = useState('Jack')
  const [age, setAge] = useState(10)
  const [isLegal, setLegal] = useState(false)
  const [friends, setFriends] = useState(["John", "Luke"])

  return <h1> Hello World! My name is {name} </h1>
}
```

And that's all there is to it. The `useState` hook basically enables function components to have its own internal state. 

## The `useEffect` hook

The `useEffect` hook is the combination of `componentDidMount`, `componentDidUpdate` and `componentWillUnmount` class lifecycle methods. This hook is the ideal place to set up listeners, fetching data from API and removing listeners before the component is removed from the DOM.

Let’s look at an example of useEffect in comparison with class lifecycle methods. Normally in class component, we write this kind of code:

```jsx
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'Nathan',
    };
  }

  componentDidMount() {
    console.log(
      `didMount triggered: Hello I'm ${this.state.name}`
    );
  }

  componentDidUpdate() {
    console.log(
      `didUpdate triggered: Hello I'm ${this.state.name}`
    );
  }

  render() {
    return (
      <div>
        <p>{`Hello I'm ${this.state.name}`}</p>
        <button
          onClick={() =>
            this.setState({ name: 'Gary'})
          }
        >
          Change me
        </button>
      </div>
    );
  }
}
```

Since `componentDidMount` is run only once when the component is inserted into the DOM tree structure, subsequent render won’t trigger the method anymore. In order to do run something on each render, you need to use `componentDidUpdate` method.

Using `useEffect` hook is like having both `componentDidMount` and `componentDidUpdate` in one single method, since useEffect runs on every render. It accepts two arguments:

* (mandatory) A function to run on every render
* (optional) An array of state variables to watch for changes. `useEffect` will be skipped if none of the variables are updated.

Rewriting the above class into function component would look like this:

```jsx
const Example = props => {
  const [name, setName] = useState('Nathan');

  useEffect(() => {
    console.log(`Hello I'm ${name}`);
  });

  return (
    <div>
      <p>{`Hello I'm ${name}`}</p>
      <button
        onClick={() => {
          setName('Gary')
          }}>
        Change me
      </button>
    </div>
  )
}
```

The function component above will run the function inside of `useEffect` function on each render. Now this isn’t optimal because the state won’t be updated after the first click. This is where `useEffect` second argument come into play.

```jsx
useEffect(() => {
    console.log(`Hello I'm ${name} and I'm a ${role}`);
  }, 
  [name]);
```

The second argument of `useEffect` function is referred to as the "dependency array". When the variable included inside the array didn't change, the function passed as the first argument won't be executed.

### The componentWillUnmount effect

If you have code that needs to run when the component will be removed from the DOM tree, you need to specify a `componentWillUnmount` effect by writing a `return` statement into the first argument function. Here is an example:

```jsx
useEffect(() => {
    console.log(`useEffect function`);

    return () => { console.log("componentWillUnmount effect"); }
  }, [name] );
```

### Running useEffect only once

To run `useEffect` hook only once like `componentDidMount` function, you can pass an empty array into the second argument:

```jsx
useEffect(
  () => {
    console.log(`useEffect function`);
  }, 
  [] );
```

The empty array indicates that the effect doesn't have any dependencies to watch for change, and without a trigger, it won't be run after the component is mounted.

## Level up your React skill today!
Get my latest book and build FOUR projects using React. You get 40% off with my Black Friday deal! [Grap a copy today!](https://sebhastian.com/digesting-react)

[![](https://dev-to-uploads.s3.amazonaws.com/i/beo4k98gjdkatcbtp1rb.png)](https://sebhastian.com/digesting-react)