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 is 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 nthe ext 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
useState
|
setState
|
useState method is used in functional component
|
setState 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 array
|
With 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 data
|
While 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. You can download the source code attached to this article. Now in the next article, we will learn about useEffect hook along with its usage in ReactJs.