Clientside Goodies
Practice React's useState hook with 8 Interactive Exercises
Put your react state management skills to the test with 8 interactive exercises.
useState
hook, is a powerful tool that simplifies state management in functional components.useState
and its practical applications. 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
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
Solution Walkthrough for Counter
Spoiler Alert!
Don't read this unless you've already solved the problem.
Key ReactJS Concepts:
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:
count
with 0:count
using the useState
hook and set its initial value to 0.const [count, setCount] = useState(0);
handleIncrement
function:handleIncrement
that increments the count
state variable by 1.function handleIncrement() {
setCount(count + 1);
}
handleIncrement
function to the button's onClick
event handler: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:
count
state variable to display the current count in a paragraph element.<p>Count: {count}</p>
2. Controlled Input Field
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
Solution Walkthrough for Controlled Input Field
Spoiler Alert!
Don't read this unless you've already solved the problem.
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:
text
with an empty string:text
using the useState
hook and set its initial value to an empty string.const [text, setText] = useState('');
handleInputChange
function: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:
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.handleInputChange
function to the input field's onChange
event handler: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:
text
state variable to display the current text in a paragraph element.<p>Input text: {text}</p>
3. Toggle Visibility
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
hook to manage the visibility stateuseState
Solution Walkthrough for Toggle Visibility
Spoiler Alert!
Don't read this unless you've already solved the problem.
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:
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:
isVisible
with false
: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);
handleToggleVisibility
function:handleToggleVisibility
that toggles the isVisible
state variable by setting it to its opposite value (!isVisible
).function handleToggleVisibility() {
setIsVisible(!isVisible);
}
handleToggleVisibility
function to the button's onClick
event handler: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>
isVisible
state:isVisible
state is true
.{isVisible && <p>Toggle me!</p>}
4. Character Counter
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
hook to manage the text stateuseState
Solution Walkthrough for Character Counter
Spoiler Alert!
Don't read this unless you've already solved the problem.
Event Handling and Controlled Components:
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);
}
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:
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:
CharacterCounter
component combines these important React concepts to create an interactive and responsive experience for users. 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
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
hook to manage the todo list stateuseState
Solution Walkthrough for Todo List
Spoiler Alert!
Don't read this unless you've already solved the problem.
Key ReactJS Concepts:
List Rendering:
map
function to iterate over the todos
array and render a list item for each todo.Event Handling:
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:
todos
and inputValue
: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('');
handleInputChange
, handleSubmit
, and handleDelete
functions:
updates thehandleInputChange
state variable whenever the input field value changes.inputValue
function handleInputChange(event) {
setInputValue(event.target.value);
}
adds a new todo item to thehandleSubmit
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.todos
function handleSubmit() {
if (inputValue.trim()) {
setTodos([...todos, inputValue.trim()]);
setInputValue('');
}
}
removes a todo item from thehandleDelete
array based on its index.todos
function handleDelete(index) {
setTodos(todos.filter((_, i) => i !== index));
}
handleInputChange
, handleSubmit
, and handleDelete
functions to the corresponding event handlers:- Attach the
function to the input field'shandleInputChange
event handler and set its value to the currentonChange
state.inputValue
<input type="text" value={inputValue} onChange={handleInputChange} />
- Attach the
function to the "Add Todo" button'shandleSubmit
event handler.onClick
<button onClick={handleSubmit}>Add Todo</button>
Display the list of todo items:
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>
useState
hook manages the todo list state, making it easy to update and maintain.
6. Color Switcher
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
hook to manage the background color stateuseState
Solution Walkthrough for Color Switcher
Spoiler Alert!
Don't read this unless you've already solved the problem.
Solution Walkthrough:
bgColor
:bgColor
using the useState
hook. This variable will store the current background color of the div.const [bgColor, setBgColor] = useState('');
handleColorChange
function: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);
}
handleColorChange
function: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>
bgColor
state: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>
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
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
hook to manage the search input stateuseState
Solution Walkthrough for Search Filter
Spoiler Alert!
Don't read this unless you've already solved the problem.
Filtering Items Based on Search Input:
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:
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:
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
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
hook to manage the list stateuseState
Solution Walkthrough for Drag and Drop List
Spoiler Alert!
Don't read this unless you've already solved the problem.
Managing Drag-and-Drop 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:
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:
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.