4 Different Examples of the useState Hook in React

Photo by Arnold Francisca on Unsplash

useState is a widely used hook in React. Almost every component you develop in React involves state. In this post, I am going to show you four different use cases of the useState hook.

I am assuming you have a basic knowledge of React and state. If not, visit the docs to get started.

Initializing State

As a reminder, I’ll go over how to initialize state. First, import useState and then, declare your state variables in the following way.

import { useState } from 'react'
const [name, setName] = useState('kunal')

setName is the function used to set the state i.e. name. It has a default value.

Do not set state directly, always use the function. Read this to know why.

Now, let’s go over some use cases.

1. Conditional Rendering

Let’s say your application has a user and you want to display something based on whether the user is an admin. You can do that with conditional rendering.

In this example, we have a set of records that all users can see. But, an admin user has the option to edit each record. First, define the user as state.

const [user, setUser] = useState({
name: 'kunal',
isAdmin: false
})

Now, render the records. tableData has the records to be displayed.

return (
<div>
<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>City</th>
{user.isAdmin && <th>Action</th>}
</tr>
{tableData.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.city} </td>
{user.isAdmin &&
<td>
<button> Edit </button>
</td>
}

</tr>
))}
</table>
</div>
)

Here, a regular user would only see the first three columns. However, an admin user would also see the 4th column which contains the Edit button.

If the isAdmin attribute is false, then the column won’t be visible.

Let’s take another example. You have two tables and you only want to render one at a time.

We have a state toggleTable that decides which table to display. You can switch between tables with a button click.

const [toggleTables, setToggleTables] = useState(false)

The two tables show different data and can be rendered as per the state value by using a conditional expression.

return (
<div>
<div>
<button onClick={handleClick} >
Show the other table
</button>
</div>
<div>
{
toggleTables ?

<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>Last Name</th>
<th>City</th>
</tr>
{tableData1.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.last_name} </td>
<td> {data.city} </td>

</tr>
))}
</table>
:
<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>City</th>
<th>Bitcoin Address</th>
<th>Credit Card</th>
<th>Card Type</th>
<th>Currency</th>
</tr>
{tableData2.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.city} </td>
<td> {data.bitcoin_address} </td>
<td> {data.credit_card} </td>
<td> {data.card_type} </td>
<td> {data.currency} </td>
</tr>
))}
</table>
}
</div>
</div>
)

And here is the handleClick function where we change the state.

const handleClick = () => {
setToggleTables(!toggleTables);
}

2. Counter

State can also be used to implement a counter. This involves keeping track of the previous state. First, have the count as state with default value 0.

const [count, setCount] = useState(0)  

Then, render the same and have two buttons to increment and decrement with onClick handlers.

<h2> {count} </h2>
<div>
<button onClick={() => { setCounter(-1) }} > Decrement </button>
<button onClick={() => { setCounter(1) }}> Increment </button>
</div>

Implement the handler function.

function setCounter(value) {
setCount(count+value);
}

Let’s also have one input field to control how much to increment or decrement the counter.

<div>
<form onSubmit={handleSubmit}>
<label> Enter a value to increment by </label>
<input type='number' />
<button type='submit' > Submit </button>
</form>
</div>

Implement the handler function. Use the same setCounter function to set the state value as per the value given by the user.

const handleSubmit = (event) => {
event.preventDefault();
setCounter(parseInt(event.target[0].value));
}

Use event.preventDefault() while submitting the form. Read more about it here.

3. Form Handling

Form Handling is a very important use case of the useState hook. You’ll encounter this everywhere.

Let’s have a basic form having the following fields. Make each field as required.

 <form onSubmit={handleSubmit}>
<input placeholder='Enter name'
onChange={(e) => {setName(e.target.value)}}
value={name} required/>
<br/>
<input type='email' placeholder='Enter email' value={email}
onChange={(e) => {setEmail(e.target.value)}} required/>
<br/>
<input type='password' placeholder='Enter password' value={password}
onChange={(e) => {setPassword(e.target.value)}} required/>
<br/>
<label>Gender</label>
<select onChange={(e) => {setGender(e.target.value)}} value={gender}
required>
<option>Male</option>
<option>Female</option>
</select>
<br/>

<button type='submit'>Submit</button>

</form>

Define the following state variables for the same.

const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [gender, setGender] = useState('')

These state variables hold the values of the form fields. You want to keep them updated along with the user input. That is done using the onChange attribute of the input element.

In real-time applications, form submissions usually take some time. So, it’s important to show the user that the form is being submitted. You can do that using another state variable.

const [isSubmitting, setIsSubmitting] = useState(false)

As soon as the submit button is clicked, set isSubmitting as true and then set it to false after submission. Meanwhile, show the user a message. Here, there is nothing that would hold up the form submission, so you won’t be able to see the message.

Let’s simulate that behavior.

const handleSubmit = (event) => {
event.preventDefault();

setIsSubmitting(true)
setTimeout(() => {
setIsSubmitting(false);
alert("Form submission successful")
}, 3000);
}

Use a setTimeout to wait a few seconds before a form gets submitted. And display a message right below the submit button.

{isSubmitting && 'Submitting...'}

4. TODO List

One of the simplest use cases of the useState hook is a simple to-do list. I am going to show you how to implement add, update, and delete functionalities.

First, have an input field and a button for adding a task. Hold the user input in a state.

const [taskInput, setTaskInput] = useState('')
<input type='text' placeholder="Name your task" value={taskInput}
onChange={(e) => { setTaskInput(e.target.value) }}/>
<button onClick={handleSubmit} >Add item</button>

Also, have a state to hold the entire to-do list.

const [todoList, setTodoList] = useState([])

Now, implement the Add button’s handleClick function.

const handleSubmit = () => {
const newTodo = {
id: new Date().getTime(),
task: taskInput,
updateFlag: false
}
setTodoList([...todoList, newTodo]);
setTaskInput('')
}

Create a new todo object having the current timestamp as its id. The updateFlag field determines whether the current item is being updated. Now, display the list with the update and delete options.

<ul>
{todoList.map(todo => (
<li key={todo.id}>
{todo.task}
<button onClick={() => {handleUpdate(todo.id)}}>Update</button>
<button onClick={() => {handleDelete(todo.id)}}>Delete</button>
</li>
))}
</ul>

For handleDelete, use the filter method to remove an element from a state array based on the id (very important to have it as unique).

function handleDelete(id) {
setTodoList(todoList.filter(todo => todo.id !== id));
}

To update an element, the user needs an input field to enter the updated value. So, use updateFlag to toggle between displaying and updating an item. For each item in the list, do the following:

{todo.updateFlag == true
? <input type='text' defaultValue={todo.task}
onChange={(e) => { setUpdateTaskInput(e.target.value) }}/>
: todo.task
}

Also, have another state variable for storing the updated input value.

const [updateTaskInput, setUpdateTaskInput] = useState()

If the updateFlag is true, the item displays a form to enter a new value.

Now, implement the handleUpdate function. The function takes the id of todo as a parameter. Return back if the updated value is empty.

function handleUpdate(id) {
if(updateTaskInput == '') return;
...
}

Updating here involves changing the individual field of an object. First, get the element from the list using the id and create another list that filters out that element.

const todo = todoList.find(todo => todo.id === id)
const updatedList = todoList.filter(todo => todo.id !== id)

Now, if the updateFlag is false, set it as true to display the input field.

if(todo.updateFlag == false) {
updatedList.push({...todo, updateFlag: true})
setTodoList(updatedList)
return;
}

Now, after entering the new value, the user clicks the update button again. Update the task name in the same function, but in the opposite condition.

updatedList.push({...todo, 
task: updateTaskInput,
updateFlag: false
})

setTodoList(updatedList);

setUpdateTaskInput('')

You can find the code in my Git repo.

Conclusion

In this article, I have shown you different examples where you can use the useState hook. You’ll encounter the first three use cases frequently in your React projects.

The fourth one is a very common example that showed you how to handle state updates in different scenarios. Do let me know if anything is incorrect.

If you are unable to understand the content or find the explanation unsatisfactory, comment your thoughts below. New ideas are always appreciated! Give a few claps if you liked this post. Subscribe and follow me for weekly content. Feel free to DM me on LinkedIn if you want to discuss anything. Till then, Goodbye!

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job


4 Different Examples of the useState Hook in React was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.

Photo by Arnold Francisca on Unsplash

useState is a widely used hook in React. Almost every component you develop in React involves state. In this post, I am going to show you four different use cases of the useState hook.

I am assuming you have a basic knowledge of React and state. If not, visit the docs to get started.

Initializing State

As a reminder, I’ll go over how to initialize state. First, import useState and then, declare your state variables in the following way.

import { useState } from 'react'
const [name, setName] = useState('kunal')

setName is the function used to set the state i.e. name. It has a default value.

Do not set state directly, always use the function. Read this to know why.

Now, let’s go over some use cases.

1. Conditional Rendering

Let’s say your application has a user and you want to display something based on whether the user is an admin. You can do that with conditional rendering.

In this example, we have a set of records that all users can see. But, an admin user has the option to edit each record. First, define the user as state.

const [user, setUser] = useState({
name: 'kunal',
isAdmin: false
})

Now, render the records. tableData has the records to be displayed.

return (
<div>
<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>City</th>
{user.isAdmin && <th>Action</th>}
</tr>
{tableData.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.city} </td>
{user.isAdmin &&
<td>
<button> Edit </button>
</td>
}

</tr>
))}
</table>
</div>
)

Here, a regular user would only see the first three columns. However, an admin user would also see the 4th column which contains the Edit button.

If the isAdmin attribute is false, then the column won’t be visible.

Let’s take another example. You have two tables and you only want to render one at a time.

We have a state toggleTable that decides which table to display. You can switch between tables with a button click.

const [toggleTables, setToggleTables] = useState(false)

The two tables show different data and can be rendered as per the state value by using a conditional expression.

return (
<div>
<div>
<button onClick={handleClick} >
Show the other table
</button>
</div>
<div>
{
toggleTables ?

<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>Last Name</th>
<th>City</th>
</tr>
{tableData1.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.last_name} </td>
<td> {data.city} </td>

</tr>
))}
</table>
:
<table>
<tr>
<th>id</th>
<th>First Name</th>
<th>City</th>
<th>Bitcoin Address</th>
<th>Credit Card</th>
<th>Card Type</th>
<th>Currency</th>
</tr>
{tableData2.map(data => (
<tr>
<td> {data.id} </td>
<td> {data.first_name} </td>
<td> {data.city} </td>
<td> {data.bitcoin_address} </td>
<td> {data.credit_card} </td>
<td> {data.card_type} </td>
<td> {data.currency} </td>
</tr>
))}
</table>
}
</div>
</div>
)

And here is the handleClick function where we change the state.

const handleClick = () => {
setToggleTables(!toggleTables);
}

2. Counter

State can also be used to implement a counter. This involves keeping track of the previous state. First, have the count as state with default value 0.

const [count, setCount] = useState(0)  

Then, render the same and have two buttons to increment and decrement with onClick handlers.

<h2> {count} </h2>
<div>
<button onClick={() => { setCounter(-1) }} > Decrement </button>
<button onClick={() => { setCounter(1) }}> Increment </button>
</div>

Implement the handler function.

function setCounter(value) {
setCount(count+value);
}

Let’s also have one input field to control how much to increment or decrement the counter.

<div>
<form onSubmit={handleSubmit}>
<label> Enter a value to increment by </label>
<input type='number' />
<button type='submit' > Submit </button>
</form>
</div>

Implement the handler function. Use the same setCounter function to set the state value as per the value given by the user.

const handleSubmit = (event) => {
event.preventDefault();
setCounter(parseInt(event.target[0].value));
}

Use event.preventDefault() while submitting the form. Read more about it here.

3. Form Handling

Form Handling is a very important use case of the useState hook. You’ll encounter this everywhere.

Let’s have a basic form having the following fields. Make each field as required.

 <form onSubmit={handleSubmit}>
<input placeholder='Enter name'
onChange={(e) => {setName(e.target.value)}}
value={name} required/>
<br/>
<input type='email' placeholder='Enter email' value={email}
onChange={(e) => {setEmail(e.target.value)}} required/>
<br/>
<input type='password' placeholder='Enter password' value={password}
onChange={(e) => {setPassword(e.target.value)}} required/>
<br/>
<label>Gender</label>
<select onChange={(e) => {setGender(e.target.value)}} value={gender}
required>
<option>Male</option>
<option>Female</option>
</select>
<br/>

<button type='submit'>Submit</button>

</form>

Define the following state variables for the same.

const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [gender, setGender] = useState('')

These state variables hold the values of the form fields. You want to keep them updated along with the user input. That is done using the onChange attribute of the input element.

In real-time applications, form submissions usually take some time. So, it’s important to show the user that the form is being submitted. You can do that using another state variable.

const [isSubmitting, setIsSubmitting] = useState(false)

As soon as the submit button is clicked, set isSubmitting as true and then set it to false after submission. Meanwhile, show the user a message. Here, there is nothing that would hold up the form submission, so you won’t be able to see the message.

Let’s simulate that behavior.

const handleSubmit = (event) => {
event.preventDefault();

setIsSubmitting(true)
setTimeout(() => {
setIsSubmitting(false);
alert("Form submission successful")
}, 3000);
}

Use a setTimeout to wait a few seconds before a form gets submitted. And display a message right below the submit button.

{isSubmitting && 'Submitting...'}

4. TODO List

One of the simplest use cases of the useState hook is a simple to-do list. I am going to show you how to implement add, update, and delete functionalities.

First, have an input field and a button for adding a task. Hold the user input in a state.

const [taskInput, setTaskInput] = useState('')
<input type='text' placeholder="Name your task" value={taskInput}
onChange={(e) => { setTaskInput(e.target.value) }}/>
<button onClick={handleSubmit} >Add item</button>

Also, have a state to hold the entire to-do list.

const [todoList, setTodoList] = useState([])

Now, implement the Add button’s handleClick function.

const handleSubmit = () => {
const newTodo = {
id: new Date().getTime(),
task: taskInput,
updateFlag: false
}
setTodoList([...todoList, newTodo]);
setTaskInput('')
}

Create a new todo object having the current timestamp as its id. The updateFlag field determines whether the current item is being updated. Now, display the list with the update and delete options.

<ul>
{todoList.map(todo => (
<li key={todo.id}>
{todo.task}
<button onClick={() => {handleUpdate(todo.id)}}>Update</button>
<button onClick={() => {handleDelete(todo.id)}}>Delete</button>
</li>
))}
</ul>

For handleDelete, use the filter method to remove an element from a state array based on the id (very important to have it as unique).

function handleDelete(id) {
setTodoList(todoList.filter(todo => todo.id !== id));
}

To update an element, the user needs an input field to enter the updated value. So, use updateFlag to toggle between displaying and updating an item. For each item in the list, do the following:

{todo.updateFlag == true
? <input type='text' defaultValue={todo.task}
onChange={(e) => { setUpdateTaskInput(e.target.value) }}/>
: todo.task
}

Also, have another state variable for storing the updated input value.

const [updateTaskInput, setUpdateTaskInput] = useState()

If the updateFlag is true, the item displays a form to enter a new value.

Now, implement the handleUpdate function. The function takes the id of todo as a parameter. Return back if the updated value is empty.

function handleUpdate(id) {
if(updateTaskInput == '') return;
...
}

Updating here involves changing the individual field of an object. First, get the element from the list using the id and create another list that filters out that element.

const todo = todoList.find(todo => todo.id === id)
const updatedList = todoList.filter(todo => todo.id !== id)

Now, if the updateFlag is false, set it as true to display the input field.

if(todo.updateFlag == false) {
updatedList.push({...todo, updateFlag: true})
setTodoList(updatedList)
return;
}

Now, after entering the new value, the user clicks the update button again. Update the task name in the same function, but in the opposite condition.

updatedList.push({...todo, 
task: updateTaskInput,
updateFlag: false
})

setTodoList(updatedList);

setUpdateTaskInput('')

You can find the code in my Git repo.

Conclusion

In this article, I have shown you different examples where you can use the useState hook. You’ll encounter the first three use cases frequently in your React projects.

The fourth one is a very common example that showed you how to handle state updates in different scenarios. Do let me know if anything is incorrect.

If you are unable to understand the content or find the explanation unsatisfactory, comment your thoughts below. New ideas are always appreciated! Give a few claps if you liked this post. Subscribe and follow me for weekly content. Feel free to DM me on LinkedIn if you want to discuss anything. Till then, Goodbye!

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job


4 Different Examples of the useState Hook in React was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


Print Share Comment Cite Upload Translate
APA
Kunal Nalawade | Sciencx (2024-04-18T16:30:44+00:00) » 4 Different Examples of the useState Hook in React. Retrieved from https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/.
MLA
" » 4 Different Examples of the useState Hook in React." Kunal Nalawade | Sciencx - Monday November 28, 2022, https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/
HARVARD
Kunal Nalawade | Sciencx Monday November 28, 2022 » 4 Different Examples of the useState Hook in React., viewed 2024-04-18T16:30:44+00:00,<https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/>
VANCOUVER
Kunal Nalawade | Sciencx - » 4 Different Examples of the useState Hook in React. [Internet]. [Accessed 2024-04-18T16:30:44+00:00]. Available from: https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/
CHICAGO
" » 4 Different Examples of the useState Hook in React." Kunal Nalawade | Sciencx - Accessed 2024-04-18T16:30:44+00:00. https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/
IEEE
" » 4 Different Examples of the useState Hook in React." Kunal Nalawade | Sciencx [Online]. Available: https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/. [Accessed: 2024-04-18T16:30:44+00:00]
rf:citation
» 4 Different Examples of the useState Hook in React | Kunal Nalawade | Sciencx | https://www.scien.cx/2022/11/28/4-different-examples-of-the-usestate-hook-in-react/ | 2024-04-18T16:30:44+00:00
https://github.com/addpipe/simple-recorderjs-demo