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.