Introduction to useState() Hook In ReactJS

Introduction

In the previous article, we have learned about ReactNative hooks and how they can be implemented in a React application. Also, we saw the concept of useState() hook. Now, in this article, we are going into detail of useState() hooks in various forms.  

useState() Hooks along with the previous state

In this, we will learn how we can set state value based on the previous state value. Let’s look at the demo in which we will see addition, multiplication, subtraction and reset a value available in Textbox. 

Create a component MathHooks.js,

import React, { useState } from 'react'      
function MathHooks() {      
    const initialVar = 1;      
    const [Var, setVar] = useState(initialVar)      
    return (      
        <div>      
            <h3> Value: {Var} <br /></h3>      
            <button onClick={() => setVar(Var + 2)}>Addition</button>      
            <button onClick={() => setVar(Var - 2)}>Subtraction</button>      
            <button onClick={() => setVar(Var * 2)}>Multiple</button>      
            <button onClick={() => setVar(initialVar)}>Reset</button>      
        </div>      
    )      
}      
export default MathHooks 

and import in App.js

import React from 'react';      
import './App.css';      
import MathHooks from './components/MathHooks'      
function App() {      
    return (      
        <div className="App">      
            <MathHooks></MathHooks>      
        </div>      
    );      
}      
export default App; 

This will display the output as below.

Now, click on the “Addition” button. It will add value by 2, here I clicked it 3 times.

Now, click on “Subtract” which will decrease the value by 2.

In the same way, click on the “Multiply” button which will multiply by 2.

Now, click on the “Reset” button. It will reinitialize the value.

The approach used in previous and this article for creating hooks for addition is unsafe; the reason and cause are displayed below. 

Add another button which will include an addition by 5.

import React, { useState } from 'react'      
function MathHooks() {      
    const initialVar = 1;      
    const [Var, setVar] = useState(initialVar)      
    const AdditionBy5 = () => {      
        for (let i = 0; i < 5; i++) {      
            setVar(Var + 1)      
        }      
    }      
    return (      
        <div>      
            <h3> Value: {Var} <br /></h3>      
            <button onClick={() => setVar(Var + 2)}>Addition</button>      
            <button onClick={AdditionBy5}>Addition by 5</button>      
            <button onClick={() => setVar(Var - 2)}>Subtraction</button>      
            <button onClick={() => setVar(Var * 2)}>Multiply</button>      
            <button onClick={() => setVar(initialVar)}>Reset</button>      
        </div>      
    )      
}      
export default MathHooks  

Now, look at the demo.

Click on addition by 5.

It is still increasing the Var value by 1 This is because setVar method is taking the old value of Var instead of the new value. 

To resolve this issue, we need to implement the second form of useState() in which instead of passing direct value of variable, we will pass an arrow function which has access to old value, and it will take old value and increment the old value by 1 and assign the new value to the variable.

import React, { useState } from 'react'      
function MathHooks() {      
    const initialVar = 1;      
    const [Var, setVar] = useState(initialVar)      
    const AdditionBy5 = () => {      
        for (let i = 0; i < 5; i++) {      
            setVar(prevVar => prevVar + 1)      
        }      
    }      
    return (      
        <div>      
            <h3> Value: {Var} <br /></h3>      
            <button onClick={() => setVar(Var + 2)}>Addition</button>      
            <button onClick={AdditionBy5}>Addition by 5</button>      
            <button onClick={() => setVar(Var - 2)}>Subtraction</button>      
            <button onClick={() => setVar(Var * 2)}>Multiply</button>      
            <button onClick={() => setVar(initialVar)}>Reset</button>      
        </div>      
    )      
}      
export default MathHooks 

The output will be displayed as below.

So, in any case where you need to update state value dynamically you should go for a safer option, now let us change the code for other available buttons.

import React, { useState } from 'react'      
function MathHooks() {      
    const initialVar = 1;      
    const [Var, setVar] = useState(initialVar)      
    const AdditionBy5 = () => {      
        for (let i = 0; i < 5; i++) {      
            setVar(prevVar => prevVar + 1)      
        }      
    }      
    return (      
        <div>      
            <h3> Value: {Var} <br /></h3>      
            <button onClick={() => setVar(prevVar => prevVar + 2)}>Addition</button>               
            <button onClick={() => setVar(prevVar => prevVar - 2)}>Subtraction</button>      
            <button onClick={() => setVar(prevVar => prevVar * 2)}>Multiply</button>      
            <button onClick={() => setVar(initialVar)}>Reset</button>    
        </div>      
    )      
}    
export default MathHooks   

The output will remain the same as above.

Similarly, it should be implemented in the class component. 

Update code in the previous article for MathClass.js.

import React, { Component } from 'react'      
class MathClass extends Component {      
    constructor(props) {      
        super(props)      
        this.state = {      
            addition: 0      
        }      
        this.incrementValue = this.incrementValue.bind(this)      
    }      
    incrementValue = () => {      
        this.setState(prevState => {      
            return {      
                addition: prevState.addition + 1      
            }      
        })      
    }      
    render() {      
        return (      
            <div>      
                <label>Added Value is {this.state.addition}</label><br></br>      
                <button onClick={this.incrementValue}>Add 1 Value</button>      
            </div>    
        )    
    }    
}    
export default MathClass   

The output will remain the same.

Now, let’s move to another example of useState(). 

useState() with objects

Now, in this case, instead of passing a single string or number in useState() function, objects will be passed. These objects can be anything like String, Numbers, Boolean, Object, Event or Array based on your requirement. 

Let’s look at the demo to create full name along with prefix, Create a component ObjectHooks.js

import React, { useState } from 'react'      
function ObjectHooks() {      
    const [name, setName] = useState({ prefix: '', firstName: '', lastName: '' })    
    return (      
        <div>      
            <form>      
                <input type="text" value={name.prefix} onChange={e => setName({ prefix: e.target.value })} />      
                <input type="text" value={name.firstName} onChange={e => setName({ firstName: e.target.value })} />      
                <input type="text" value={name.lastName} onChange={e => setName({ lastName: e.target.value })} />      
                <h2>Your full name is {name.prefix} {name.firstName} {name.lastName}</h2>      
            </form>      
        </div>      
    )      
}      
export default ObjectHooks  

import in App.js

import React from 'react';      
import './App.css';      
import ObjectHooks from './components/ObjectHooks'      
function App() {      
   return (      
      <div className="App">      
         <ObjectHooks></ObjectHooks>      
      </div>      
   );      
}      
export default App; 

This will display output as below.

You will notice that output is weird as when typing in the first textbox it is displaying the value, and as soon as it switches to the textbox it clears the value of previous ones,  and only take current one,  because useState will not merge the state, unlike setState in-class component. 

So, to do that in functional component, we need to do it manually using the spread operator as shown in the code below,

import React, { useState } from 'react'      
function ObjectHooks() {      
    const [name, setName] = useState({ prefix: '', firstName: '', lastName: '' })    
    return (      
        <div>      
            <form>      
                <input type="text" value={name.prefix} onChange={e => setName({ ...name, prefix: e.target.value })} />      
                <input type="text" value={name.firstName} onChange={e => setName({ ...name, firstName: e.target.value })} />      
                <input type="text" value={name.lastName} onChange={e => setName({ ...name, lastName: e.target.value })} />      
                <h2>Your full name is {name.prefix} {name.firstName} {name.lastName}</h2>      
            </form>      
        </div>      
    )      
}      
export default ObjectHooks 

This spread operator dictates the method that creates a replica of the whole object and just updates the followed property, 

Now check the output below, type the prefix for the name,

Add your first name,

Adding the last name,

Now state value is maintained and not lost. 

useState with Array

In this scenario, we will learn about how to use useState when using Array, 

Let’s look at the demo,

import React, { useState } from 'react'    
    
function ArrayHooks() {    
    const [lists, setLists] = useState([])    
    
    const addList = () => {    
        setLists([...lists, {    
            id: lists.length,    
            value: Math.floor(Math.random() * 5) + 1    
        }])    
    }    
    
    return (    
        <div>    
            <button onClick={addList}>Add List Item</button>    
            <ul>    
                {    
                    lists.map(list => (    
                        <li key={list.id}>{list.value}</li>    
                    ))    
                }    
            </ul>    
        </div>    
    )    
}      
export default ArrayHooks   

Import the file in App.js

import React from 'react';  
import './App.css';  
import ArrayHooks from './components/ArrayHooks'  
  
function App() {  
  return (  
    <div className="App">  
      <ArrayHooks></ArrayHooks>  
    </div>  
  );  
}  
  
export default App;  

This will display output as below,

Now click on the button,

It will add items to list and numbers are generated randomly. In this, we just need to use the spread operator to copy the object and append new values to the array and assign in setLists() function. 

Difference between useState and setState

useStatesetState
useState method is used in functional componentsetState method is used in class components
With useState hook, the state does not have to be the object it can be anything like string, number, Boolean, object or arrayWith setState, a state is always an object
When using array or object in useState always remember to use spread operator followed by setter function to merge dataWhile using setState it will always store the values so no need for explicitly merge array or object

Summary

In this article, we have learned about useState along with 3 different examples like using useState to access previous state value, useState to use with Object and Arrays.

Now in the next article, we will learn about useEffect hook along with its usage in ReactJs.

Any question or feedback or suggestion, please do comment and let me know.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s