Clientside Goodies

Practice React's useState hook with 8 Interactive Exercises

Put your react state management skills to the test with 8 interactive exercises.

React's
useState
hook, is a powerful tool that simplifies state management in functional components.
In this article, we'll dive into 8 interactive exercises that will help you gain a deeper understanding of React's
useState
and its practical applications.
These exercises are designed to challenge your existing knowledge, reinforce your understanding, and elevate your skill set. By the end of this post, you'll be able to confidently use
useState
in your projects, optimize state management, and build more robust and maintainable React applications.

So, grab some coffee or tea and let's get started!

1. Counter

Easy

In this exercise, you’re tasked with creating a simple counter component that increments a number every time a button is clicked.

Expectations:

  • Every time the button is clicked, the number should increment by 1

  • Display the current number state in the text element

Console
Submit
Solution
00:00

Solution Walkthrough for Counter

Key ReactJS Concepts:

Event Handling: React supports various event handlers, such as
onClick
, which allows you to execute a function when an element is clicked. In this exercise, we'll use the
onClick
event handler to increment the counter when the button is clicked.

Solution Walkthrough:

Initialize state variable
count
with 0:
We create a state variable
count
using the
useState
hook and set its initial value to 0.
const [count, setCount] = useState(0);
Create the
handleIncrement
function:
We create a new function called
handleIncrement
that increments the
count
state variable by 1.
function handleIncrement() {
  setCount(count + 1);
}
Attach the
handleIncrement
function to the button's
onClick
event handler:
We connect the
handleIncrement
function to the
onClick
event handler of the button. This ensures that the function is called every time the button is clicked.
<button onClick={handleIncrement}>Increment</button>

Display the current count:

We use the
count
state variable to display the current count in a paragraph element.
<p>Count: {count}</p>

2. Controlled Input Field

Easy

Create an input field component that allows a user to type in text and displays the text in real-time.

  • Every time the user types something in the input field, the text should update in the text element

  • You should use the useState hook to keep track of the text state

Console
Submit
Solution
00:00

Solution Walkthrough for Controlled Input Field

Key ReactJS Concepts:

Controlled Components:

In React, a controlled component is a component where the state of the input field is directly controlled by React. The value of the input field is set by a state variable, and any change in the value triggers an event handler to update the state.

Solution Walkthrough:

Initialize state variable
text
with an empty string:
We create a state variable
text
using the
useState
hook and set its initial value to an empty string.
const [text, setText] = useState('');
Create the
handleInputChange
function:
We create a new function called
handleInputChange
that takes the
event
object as a parameter. This function is responsible for updating the
text
state variable with the current value of the input field.
function handleInputChange(event) {
  setText(event.target.value);
}

Set up the controlled input field component:

In the component's JSX, we set the
value 
attribute of the input field to the current text state. This makes the input field a controlled component, as its value is directly controlled by React.
Attach the
handleInputChange
function to the input field's
onChange
event handler:
We connect the
handleInputChange
function to the
onChange
event handler of the input field. This ensures that the function is called every time the input field's value changes.
<input type="text" value={text} onChange={handleInputChange} />

Display the text in real-time:

Finally, we use the
text
state variable to display the current text in a paragraph element.
<p>Input text: {text}</p>

3. Toggle Visibility

Easy

In this exercise, you're tasked with creating a component that toggles the visibility of a piece of text when a button is clicked. Expectations:

  • Initially, the text should be hidden

  • When the button is clicked, the text should become visible if it was hidden, and hidden if it was visible

  • Use the
    useState
    hook to manage the visibility state

Console
Submit
Solution
00:00

Solution Walkthrough for Toggle Visibility

Key ReactJS Concepts:

Conditional Rendering:

React allows you to conditionally render elements based on a certain condition. In this exercise, we'll use conditional rendering to display or hide the text element based on the visibility state.

Event Handling:

React supports various event handlers, such as
onClick
, which allows you to execute a function when an element is clicked. In this exercise, we'll use the
onClick
event handler to toggle the visibility state when the button is clicked.

Solution Walkthrough:

Initialize state variable
isVisible
with
false
:
We create a state variable
isVisible
using the
useState
hook and set its initial value to
false
, indicating that the text should be initially hidden.
const [isVisible, setIsVisible] = useState(false);
Create the
handleToggleVisibility
function:
We create a new function called
handleToggleVisibility
that toggles the
isVisible
state variable by setting it to its opposite value (
!isVisible
).
function handleToggleVisibility() {
  setIsVisible(!isVisible);
}
Attach the
handleToggleVisibility
function to the button's
onClick
event handler:
We connect the
handleToggleVisibility
function to the
onClick
event handler of the button. This ensures that the function is called every time the button is clicked, toggling the visibility of the text element.
<button onClick={handleToggleVisibility}>Show/Hide Text</button>
Conditionally render the text element based on the
isVisible
state:
We use conditional rendering to display the text element only if the
isVisible
state is
true
.
{isVisible && <p>Toggle me!</p>}

4. Character Counter

Medium

Create a simple Character Counter component that allows users to type in text and displays the number of characters in real-time.

Expectations:

  • Create a textarea element for users to type in text

  • Display the character count below the textarea in real-time

  • Use the
    useState
    hook to manage the text state

Console
Submit
Solution
00:00

Solution Walkthrough for Character Counter

Event Handling and Controlled Components:

React uses synthetic events to handle user interactions, such as changes to input fields. In this component, we need to respond to changes in the textarea's value. We create a function called
handleTextareaChange
that accepts an event object as its parameter. This event object contains information about the change, including the new value of the textarea. The function updates the
text
state variable with the updated value:
function handleTextareaChange(event) {
  setText(event.target.value);
}
We use the
handleTextareaChange
function as an event handler, attaching it to the
onChange
event of the textarea. Remember: this pattern of explicitly setting the value of an input field and providing an event handler to update the state is known as a controlled component in React:
<textarea value={text} onChange={handleTextareaChange} />

Real-time Updates and React's Re-rendering:

One of React's core features is its ability to efficiently re-render components when their state or props change. By connecting the
text
state to the textarea's value and the displayed character count, React will automatically re-render the component whenever
text
is updated. This ensures that the character count displayed below the textarea always reflects the current length of the text:
<p>Character count: {text.length}</p>

Putting It All Together:

The final
CharacterCounter
component combines these important React concepts to create an interactive and responsive experience for users.
The
useState
hook manages the component's state, while the controlled component pattern ensures that the textarea's value is always in sync with the state. React's re-rendering mechanism guarantees that the displayed character count updates in real-time as the user types in the textarea.

5. Todo List

Easy

In this exercise, you are tasked with creating a simple Todo List component that allows users to add new items to the list and delete items once they are completed. The Todo List should have the following features:

  • An input field for adding new todo items

  • A button to submit the new todo item

  • Display the list of todo items

  • A delete button next to each todo item to remove it from the list

  • Use the
    useState
    hook to manage the todo list state

Console
Submit
Solution
00:00

Solution Walkthrough for Todo List

Key ReactJS Concepts:

List Rendering:

React allows you to render lists by iterating over arrays and creating elements for each item. In this exercise, we'll use the
map
function to iterate over the
todos
array and render a list item for each todo.

Event Handling:

React supports various event handlers, such as
onClick
and
onChange
, which allow you to execute functions when specific events occur. In this exercise, we'll use the
onClick
event handler to handle the submission and deletion of todo items, and the
onChange
event handler to update the input field value.

Solution Walkthrough:

Initialize state variables
todos
and
inputValue
:
We create two state variables using the
useState
hook.
todos
is an array that stores the list of todo items, and
inputValue
stores the current value of the input field.
const [todos, setTodos] = useState([]);
const [inputValue, setInputValue] = useState('');
Create the
handleInputChange
,
handleSubmit
, and
handleDelete
functions:
  • handleInputChange
    updates the
    inputValue
    state variable whenever the input field value changes.
function handleInputChange(event) {
  setInputValue(event.target.value);
}
  • handleSubmit
    adds a new todo item to the
    todos
    array when the "Add Todo" button is clicked. Before adding the item, it checks if the trimmed input value is not empty to prevent adding empty or whitespace-only items.
function handleSubmit() {
  if (inputValue.trim()) {
    setTodos([...todos, inputValue.trim()]);
    setInputValue('');
  }
}
  • handleDelete
    removes a todo item from the
    todos
    array based on its index.
function handleDelete(index) {
  setTodos(todos.filter((_, i) => i !== index));
}
Attach the
handleInputChange
,
handleSubmit
, and
handleDelete
functions to the corresponding event handlers:
  • Attach the
    handleInputChange
    function to the input field's
    onChange
    event handler and set its value to the current
    inputValue
    state.
<input type="text" value={inputValue} onChange={handleInputChange} />
  • Attach the
    handleSubmit
    function to the "Add Todo" button's
    onClick
    event handler.
<button onClick={handleSubmit}>Add Todo</button>

Display the list of todo items:

We use the
map
function to iterate over the
todos
array, rendering a list item for each todo. We also attach a "Delete" button to each list item with the
handleDelete
function, passing the item's index.
<ul>
  {todos.map((todo, index) => (
    <li key={index}>
      {todo}
      <button onClick={() => handleDelete(index)}>Delete</button>
    </li>
  ))}
</ul>
Now, users can add new todo items to the list and delete them once they are completed. The
useState
hook manages the todo list state, making it easy to update and maintain.

6. Color Switcher

Medium

In this exercise, you are tasked with creating a simple Color Switcher component that allows users to change the background color of a div by selecting a color from a dropdown list.

Expectations:

  • Create a dropdown list with a few color options (e.g., red, blue, green, yellow)

  • When a color is selected from the dropdown, the background color of the div should change to the selected color

  • Use the
    useState
    hook to manage the background color state

Console
Solution
00:00

Solution Walkthrough for Color Switcher

Solution Walkthrough:

Initialize the state variable
bgColor
:
We create a state variable called
bgColor
using the
useState
hook. This variable will store the current background color of the div.
const [bgColor, setBgColor] = useState('');
Create the
handleColorChange
function:
We define a function called
handleColorChange
that updates the
bgColor
state variable whenever a new color is selected from the dropdown. This function takes the event object as a parameter and sets the state using the selected color value.
function handleColorChange(event) {
  setBgColor(event.target.value);
}
Render the dropdown with color options and attach the
handleColorChange
function:
In the return statement, we render a dropdown list with color options (red, blue, green, and yellow). We attach the
handleColorChange
function to the dropdown's
onChange
event handler.
<select onChange={handleColorChange}>
  <option value="">Select a color</option>
  <option value="red">Red</option>
  <option value="blue">Blue</option>
  <option value="green">Green</option>
  <option value="yellow">Yellow</option>
</select>
Create a div and set its background color based on the
bgColor
state:
We create a div element and use inline styling to set its background color. The background color is determined by the current value of the
bgColor
state variable. We also set the width and height of the div for better visibility.
<div style={{ backgroundColor: bgColor, width: '100px', height: '100px' }}></div>
When the user selects a color from the dropdown list, the
handleColorChange
function is called. This function updates the
bgColor
state with the new color value, causing the background color of the div to change accordingly.

7. Search Filter

Medium

In this exercise, you are tasked with creating a simple Search Filter component that allows users to filter a list of items based on their search input.

Expectations:

  • Create an input field for users to type in their search query

  • Display the list of items and filter them based on the user's search input

  • Use the
    useState
    hook to manage the search input state

Console
Submit
Solution
00:00

Solution Walkthrough for Search Filter

Filtering Items Based on Search Input:

The core functionality of the SearchFilter component is to filter a list of items based on the user's search input. To achieve this, we create a new constant
filteredItems
that filters the original
items
array using the
Array.prototype.filter()
method. We check if each item in the array includes the search term, ignoring case:
const filteredItems = items.filter(item =>
  item.toLowerCase().includes(search.toLowerCase())
);

This approach efficiently filters the list of items based on the user's search input, allowing us to display only the items that match the search criteria.

Rendering Filtered Items:

After filtering the list, we need to render the filtered items within the component. We use the
Array.prototype.map()
method to iterate through the
filteredItems
array and create a list item for each element. This way, we dynamically display the filtered list of items:
<ul>
  {filteredItems.map((item, index) => (
    <li key={index}>{item}</li>
  ))}
</ul>

SearchFilter Component:

The final
SearchFilter
component combines the concepts of controlled components and state management with the filtering functionality to create a responsive search experience for users. As the user types in the search input, the list of items is updated in real-time, reflecting the filtered results based on the user's input.

8. Drag and Drop List

Hard

In this exercise, you are tasked with creating a simple Drag and Drop List component that allows users to reorder a list of items by dragging and dropping them. The Drag and Drop List should have the following features:

  • Display the list of items

  • Allow users to drag and drop items to reorder the list

  • Use the
    useState
    hook to manage the list state

Console
Solution
00:00

Solution Walkthrough for Drag and Drop List

Managing Drag-and-Drop State:

To implement drag-and-drop functionality, we'll need to manage two pieces of state:
items
and
draggingItem
.
items
represents the current order of the list items, while
draggingItem
tracks the index of the item being dragged. We use the
useState
hook to manage both of these state variables:
const [items, setItems] = useState(initialItems);
const [draggingItem, setDraggingItem] = useState(null);

Handling Drag-and-Drop Events:

We'll need to handle three drag-and-drop events to enable list reordering:

onDragStart
: Triggered when the user starts dragging an item. We define the
handleDragStart
function that takes the index of the dragged item and updates the
draggingItem
state:
function handleDragOver(index) {
  if (draggingItem === null) return;
  if (draggingItem === index) return;

  const newItems = [...items];
  const draggingItemValue = newItems[draggingItem];
  newItems.splice(draggingItem, 1);
  newItems.splice(index, 0, draggingItemValue);

  setDraggingItem(index);
  setItems(newItems);
}
onDragEnd
: Triggered when the user drops the dragged item. We define the
handleDragEnd
function that resets the
draggingItem
state to
null
:
function handleDragEnd() {
  setDraggingItem(null);
}

Rendering Draggable List Items:

We render the list items with the
draggable
attribute and attach the appropriate event handlers for the drag events:
<ul>
  {items.map((item, index) => (
    <li
      key={index}
      draggable
      onDragStart={() => handleDragStart(index)}
      onDragOver={() => handleDragOver(index)}
      onDragEnd={handleDragEnd}
    >
      {item}
    </li>
  ))}
</ul>

DragDropList Component:

The final
DragDropList
component combines state management, event handling, and rendering to create a user-friendly drag-and-drop experience for reordering list items.

Ready to dive deeper?

Explore our library of frontend interview problems taken from interviews at top tech companies. Level up your skills.