React Hooks introduction—useState

Key takeaways:

  • The useState Hook allows functional components to manage the local state efficiently, eliminating the need for class components and making code simpler, more readable, and modular.

  • React automatically rerenders components when their state changes, but the rerender is optimized to update only the affected parts of the DOM.

  • You can store strings, numbers, booleans, arrays, or objects in the state using useState. Unlike the merging behavior in class components, each state update fully replaces the previous value.

  • Functional components can call useState multiple times to manage independent pieces of state, improving component organization and maintainability.

What are React Hooks?

React Hooks, such as the useState Hook, are functions that let you manage state and life cycle events directly in functional components. Before Hooks, you needed to use class components to handle state and component life cycle methods like componentDidMount or componentDidUpdate.

Hooks allow developers to handle both state and side effects in functional components, making the code cleaner and easier to maintain. Hooks were introduced in React 16.8.

Rules when using Hooks

  • You should call Hooks only at the top level of the component, meaning they should not be called inside loops, conditions, or nested functions.

  • You should call hooks only in React functional components or within custom Hooks. Hooks won’t work in class components or regular JavaScript functions outside the React environment.

The useState Hook

The useState ook is one of the most commonly used hooks. It allows components to manage the state easily. It accepts an initial value and returns an array containing the current state value and a function to update it. Every time you call the state update function, React triggers a rerender to reflect the new state in the UI. The syntax to define it is as follows:

const [state, setState] = useState(initialValue);
Syntax of the useState hook

In the syntax above, we have the following:

  • state: The current value of the state.

  • setState: The function that is used to update the state.

  • initialValue: The initial value of the state when the component first renders.

Let’s look at an example of using the useState Hook to manage the state of a text input.

Explanation

  • Line 1: We import the useState hook from React.

  • Line 4: We initialize the state with an empty string using useState('').

  • Line 12: We bind the value state to the input field.

  • Line 13: The onChange event updates the state every time the input value changes. It calls the setValue function that updates the value state with the text typed in the input field.

Explore the useState Hook by implementing it in a real world use case in this project, “Build a Task Manager Using React.”

Multiple state variables with useState

Unlike class components, where the state is managed within a single object, functional components can call useState multiple times to manage multiple variables.

Let’s consider another example below where we define multiple state variables:

Explanation

  • Line 4: We initialize the fName state with an empty string. It will store the current value of the first name input field.

  • Line 5: We initialize the lName state to store the last name value.

  • Line 6: We initialize the age state with an empty string to store the user’s age.

  • Line 7: We initialize the submittedData state that will store the submitted data in the form of an object.

  • Lines 9–23: We define the handleSubmit function that will store the current input values—fName, lName, and age—into the submittedData state. This ensures that the form data is captured and displayed after submission. It also resets the input fields by clearing their state and preparing the form for new entries.

  • Lines 29–37: We bind the input field for the first name to the fName state. Whenever a user enters anything in the input field, we update the fName state using the setFName function.

  • Lines 41–49: We bind the input field for the last name to the lName state. Whenever a user enters anything in the input field, we update the lName state using the setLName function.

  • Lines 53–61: We bind the input field for the age to the age state. Whenever a user enters anything in the input field, we update the age state using the setAge function.

Practice using multiple states in a component with this project, “Build an Image Sharing App with MERN Stack.”

Using booleans, arrays, and objects in useState

You can store booleans, arrays, and objects in the state, just like primitive data types. Let’s look at a working example for each of these.

1. Boolean in useState

In this example, we demonstrate how to toggle the visibility of a component using a boolean state. The isVisible state stores a true/false value representing whether the text is visible. The toggleVisibility function negates the previous state, switching between true and false. The text in the <p> tag is only rendered when isVisible is true.

2. Arrays in useState

In this example, we demonstrate how to add and display items dynamically using an array state. The tasksList state stores an array of task strings. The setTasksList uses the spread operator to retain the previous tasks and add the new ones. The tasks are rendered using .map() to generate list items dynamically.

3. Objects in useState

The profile state stores multiple fields—firstName, lastName, and email. We then define the handleChange function that uses the spread operator to preserve the previous state while updating only the targeted field. Finally, the handleSubmit function prevents the page reload and logs the complete profile object.

Continue learning the useState hook

Explore these projects for hands-on practice on the useState Hook to gain a deeper understanding of managing state within functional components.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Can useState hold complex data types?

Yes, useState can store strings, numbers, booleans, objects, and arrays. When working with objects or arrays, use spread operators to update the state without mutation.


What happens if I call useState inside a loop?

Calling useState inside a loop will break React’s rules of Hooks, causing unexpected behavior. React relies on the order in which hooks are called to associate state with a specific component instance. If useState is used inside a loop, React may not preserve the state correctly between renders, leading to bugs or errors. For this reason, hooks like useState must always be called at the top level of the component, ensuring they execute in the same order on every render.


How does useState differ from this.setState in class components?

  • this.setState merges the new state with the previous state.

  • useState replaces the entire state with the new value.

Want to learn more about setState(), read this: How to use setState in a React counter component.


Free Resources

Attributions:
  1. undefined by undefined