How to Use State in React Without Classes: The State Hook

Classless Components (aka Function Components) and State: A Quick Overview with Syntax and Examples

Roman Tetelbaum
Nerd For Tech
4 min readApr 5, 2021

--

State Hook Example from: https://reactjs.org/docs/hooks-overview.html

What are hooks?

Prior to React 16.8 which was released in February of 2019, if you wanted to use state in your React components you would have to refactor your existing code from a function component to a class component. With this React update, however, you have the option of using hooks, or “functions that let you “hook into” React state and lifecycle features from function components.” This article focuses on hooking into state, but there are other hooks available, for example if you want to access lifecycle methods in your function components you would opt for the effect hook. You may be used to using lifecycle methods such as componentDidMount and componentDidUpdate in your class components. Where state hooks allow you to hook into state functionality without using class components, effect hooks allow you to hook into lifecycle functionality in the same manner.

Why the change?

According to the React team there are many reasons for the introduction of hooks to the framework. This is beyond the scope of this article and I encourage you to read the React documentation to better understand what hooks can offer. The most important thing to note is that using hooks is completely backwards compatible, meaning if you choose to add or change just one or a few components in your code to use and test them, it will not break your existing code. Furthermore, at the time of this writing, there are no plans by the React team to remove classes from React. Hooks do not necessarily have to replace class components, but they do aim to solve some issues that programmers encounter when designing projects with a large number of components and a complex component hierarchy.

Code Example: The Old Way and the New

Let’s recall that in React our components are controlled, meaning they never read directly from the DOM and we use state instead, for example, to manage what is typed into a form by a user, character by character. In the example below I am using a class component with state for a simple contact form where the user enters their name, email, and the message they would like to send to the website admin:

For the purposes of this example, this code will not submit the form via email or any other action, but will instead only alert the user that the information they entered has been submitted. Again, we are using a controlled component where the contents of the form are updated as the user types using state and the changeHandler function, and submitted using the submitHandler function which prevents the default behavior of the form to make a new network request and re-render the entire page, alerts the user that the form has been submitted, and resets the form fields to empty strings. Let’s take a look at the exact same component refactored to use a function component with a state hook:

Let’s review some of the fundamental differences between the two components:

  1. Take a look at our import statement, where we are importing useState in addition to React (line 1).
  2. Using JavaScript’s array destructuring, we create a new state variable with useState, e.g. name where the first item is the current value and the second item is a function that let’s us update that state variable. We do the same for the email and message state variables (lines 5–7).
  3. Notice that the value attribute in the form input elements no longer references {this.state.name}, {this.state.email}, and {this.state.message} but instead references the state variable directly with {name}, {email}, and {message}(lines 24, 26, 28).
  4. Lastly, while we still use a submitHandler, there is no more changeHandler in our code, and we can call the state variable’s update function directly in the form input element’s onChange attribute as a callback function (lines 24, 26, 28).

Further Considerations

React for some time didn’t offer a way to efficiently share state between components without manually passing down props through each individual child component, and passing those props to components that were not directly related was cumbersome and difficult to keep track of. You may be familiar with a state management library such as Redux that tries to solve this problem. With React hooks and using the native React Context API, external libraries are not necessarily required, and I will cover context in an upcoming article so stay tuned!

References and Additional Resources

--

--