We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to apply for this job!

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Engineers who find a new job through WorksHub average a 15% increase in salary 🚀

Blog hero image

A Complete Beginner's Guide to React useState hook [Part 1]

Abhinav Anshul 11 May, 2021 | 5 min read

Hi 👋

In this article, we will deep dive into the world of React hooks, useState in particular from a beginner's point of view. React Hooks are the result of a continuous rise in functional programming over the years.

We will have a look at its working, common mistakes we are likely to encounter, comparing it with class-based components and best practices.

useState is a React Hook introduced late in October 2018, which allows us to have state variables in the JSX functional component. we pass an initial value to this function, and it returns a variable with a new state based on functional logic.

Let's go through the following topic one-by-one:

  • What is React useState hook?
  • Declaration useState hook in React
  • Understanding & implementation using a simple counter application.
  • Comparing it to a class-based component
  • Handling multiple states in a single component.
  • Gotchas
  • Common Mistakes
  • Why someone would use a hook?

1. What is React useState hook?

Hmm, an interesting question! As we stated earlier, the useState hook allows us to have state variables in the JSX functional component. It takes one argument which is the initial state and returns a state value and a function to update it.

2. Declaration of useState hook

useState is a named export from React, So, we can either do

import { useState } from 'react'

or simply,

React.useState

The former approach is much common across codebases and mentioned in the official react docs

3. Understanding and Implementation

It's always a good idea to try things out ourselves rather than reading documentation, so let's jump right into the code.

We'll build a counter application and to keep things simpler, we won't go into prevState (yet), see point 7(ii)

As we can see, we are importing the useState hook at top of the file, and a handful of CSS styles to keep things centered and clean enough.

Moving further, we have a functional JSX component called App, which is rendering increment and decrement buttons and a count text in between. This count will render every time the state gets updated by the button clicks.

The useState hook takes an initial state, count in this case, and returns a pair of variables, count and setCount, where count is the current state (currently set to 0) whereas setCount is a function which updates it asynchronously.

At line number 6, we are using array destructuring to return the pair of variables at array index of 0 & 1.

(Read more about array destructuring here)

Moving on, both the button has an onClick event, which triggers an anonymous function, which increments or decrements the count variable using the setCount function. This click even results in the re-rendering of the count state.

Similar to the count state variable, we are allowed to use different data types such as objects, arrays, strings, boolean, etc.

const [firstname, setFirstname] = useState("")
const [age, setAge] = useState(0)
const [isLoggedin, setIsLoggedin] = useState(false)
const [form, setForm] = useState({
    username : "",
    password : ""
})

As we can see, all the above useState hooks are valid state data types.

4. Comparing it to a class-based component

While the useState hook is a new addition to the React library, it somewhat does the same thing as this.state used with class-based components. Confused?
Let's see how we would write the same counter app in a class based component.

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  // change code below this line

  increment() {
    this.setState({
      count: this.state.count + 1
    });
  };
  
  decrement() {
    this.setState({
      count: this.state.count - 1
    });
  };

  render() {
    return (

   <div>
   <button className='inc' onClick={(e) => this.increment(e)}>Increment!</button>
    <button className='dec' onClick={(e) => this.decrement(e)}>Decrement!</button>
  <h1>Current Count: {this.state.count}</h1>
  </div>
    );
  }
};


Join our newsletter
Join over 111,000 others and get access to exclusive content, job opportunities and more!

5. Handling multiple states in a single component

Oh! what if we have multiple states to handle and not just a silly count variable, what about then? Where do we store those variables? Are they similar to this.state?

Well, handling of multiple state variables is somewhat different in useState compared to this.state In useState, we tend to write as many state hooks as there are states Like this,

const [lastname, setLastname] = useState(null)
const [firstname, setFirstname] = useState(null)
const [age, setAge] = useState(0)

Or group similar things together using an initial state object

const [islogin, setIslogin] = useState({
	username : "",
	password : ""
})

However, when building quite a large application it is incredibly difficult to keep track of all the useState hooks and is not very practical, hence useReducer comes into the picture, which is beyond the scope of this article. Read more about useReducer here

6. Gotchas

i. We can only use useState (or any other hook) inside a function component.

ii. React Hooks must be called in the same order in every component render, in simpler words, any hook should be at the very top and inside the function component without any unnecessary check, loops, etc For example, the following code is wrong, and won't behave as we expect

function App(){
	if(true){
		const [count, setCount] = useState(0)
	}
}

iii When we update the state, the component re-renders each time.

7. Common Mistakes

i. Never ever update the state directly, like this :

function incrementCount(){
	count = count + 1
}

Instead, we have a function (remember setCount function?) that will manipulate the state variable as we need, Similar to this,

function incrementCount(){
	setCount(count + 1)
}

Or, we can use an anonymous function like how we used it in the first counter application.

ii. Remember, how we talked about, "Keeping things simpler" at the very beginning of this article, well, this is the moment!

In order to use useState effectively, we absolutely want to change and mutate the state variable based on its initial state, and don't want unexpected rendering. To do so, we need to pass a previous state parameter to the function and based on that, mutating the state variable. Confused? Okay, Let's see some code!

setCount(count + 1)

should be

setCount(prevState => prevState + 1)

Here, prevState ensures us to give us current value of count no matter what, and in fact a better and recommended way to write hooks!

8. Why someone would use a hook?

i. Easier to test.

ii. Provides good readability.

iii. Performance boost.

iv. Reduction in bundle size.

Important Resources that I have collected over time 😃

i. https://medium.com/@quinnlashinsky/destructuring-arrays-in-javascript-2cb003160b3a

ii. https://levelup.gitconnected.com/react-hooks-gotchas-setstate-in-async-effects-d2fd84b02305

iii. https://www.youtube.com/watch?v=O6P86uwfdR0&t=221s&ab_channel=WebDevSimplified

Author's avatar
Abhinav Anshul
Frontend Engineer | Doing all things JavaScript | Building React Component Library
    JavaScript
    React
    CSS
    Node.js

Related Issues

cosmos / gaia
  • Started
  • 0
  • 4
  • Intermediate
  • Go
cosmos / gaia
  • Started
  • 0
  • 3
  • Intermediate
  • Go
cosmos / ibc
  • Open
  • 0
  • 0
  • Intermediate
  • TeX
cosmos / ibc
cosmos / ibc
  • Started
  • 0
  • 1
  • Intermediate
  • TeX
viebel / klipse-clj
viebel / klipse-clj
  • Started
  • 0
  • 4
  • Intermediate
  • Clojure
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 2
  • Intermediate
  • Clojure
viebel / klipse
  • Started
  • 0
  • 4
  • Intermediate
  • Clojure
  • $80

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through WorksHub average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email