Using React Hooks to manage local state with Functional Components

Stefan Nagey
Capbase Engineering
4 min readJan 12, 2019

In Part 1, we talked about the issues with the traditional class-based react approach, and how functional programming can help alleviate some of that pain. In this part of my five part series, we’re going to look at how we can use the new React Hooks api (in the forthcoming React 16.8) to maintain a long-standing state while still living in the functional world of the so-called stateless components.

Functions are great, but what about my persistent state?

With the approach I’ve described in part 1, it’s easy to see where some problems come in. What if I want to change my interface based on the user’s interaction with it? What if I want my interface to, y’know, *react*?

Let’s take a simple case. We have a page that has a button, and when you click the button, it changes the background color of the page. The base component for this might look something like this:

const Page = () => {
const onColor = “#059ed8”;
const offColor = “#343a40”;

const isItOn = true;

const color = (isItOn) ? onColor : offColor;

return (
<div style={ color } >
<button />
</div>
);
);

OK, so, this is fine, but it doesn’t do what we want. How do we change the background?

In order to do that, we need to 1) keep track of the current state (on versus off), and 2) have the button change that state.

How React Hooks solve functional problems — tracking state with useState

In our first problem above, we need to keep track of the state.

What if I told you that I can give you a magic variable that you can change and it will instantly update everything.

Technically, I’ll give you a variable and a function to change it, but it’ll still be magic.

For our above example, I’ll in one line that lets you persist a state for our isItOn variable (setting its initial value to true as well).

const [isItOn, …rest] = React.useState(true)

Now, isItOn will be true, and will persist that. I’ve discarded the rest (we’ll get to that in a minute).

Functional handlers for functional components

Ok, so, now we have our state, but how do we use it / how do we modify it such that we can update our UI?

What comes into play now is the second variable that we had previously discarded, which we will now go into.

This second value is a function handle that we can pass in a new value to.

Let’s change our above code to the following:

const [isItOn, setIsItOn] = React.useState(true)

Now we can call setIsItOn(false) to change our state (or change it to any other value we like.

Let’s now create a simple toggle handler for the button that we have above.

const toggleIsItOn = () => setIsItOn(!isItOn);

This function will change that state value, and will (eventually) trigger another call of this function, where the value of the state variable has changed to this new value.

Putting it together

Ok, so now we’ve seen how the useState call can be used to bring us persistent state that can be used to track user interactions with our UI.

Let’s update our markup to include all the useState call and our button handler:

const Page = () => {
const onColor = “#059ed8”;
const offColor = “#343a40”;

const [isItOn, setIsItOn] = React.useState(true);

const toggleIsItOn = () => setIsItOn(!isItOn);

const color = (isItOn) ? onColor : offColor;

return (
<div style={ color } >
<button onClick={toggleIsItOn} />
</div>
);
);

Super simple, right?

Now, when this button is clicked, our toggleIsItOn function will be called, and this will trigger a re-render of our component, toggling our background color.

Of course, this doesn’t help us if we want to track state over multiple components, but that’s where contexts come in.

Wrapping it all up

As we’ve seen, React Hooks give us an easy way to handle state without having to rely on long-lived objects to store our classes, and how you can write functional components for React, the so-called stateless components, but still manage state.

In the next part, we’re going to look at larger, more complex states, and how you can completely replace your existing flux or redux action/reducer workflows with much simpler React Hooks workflows leveraging the `useReducer` hook.

If you’ve not seen it, please also check out Part 1: Problems with React’s Object-based model and Functional programming, as well as the forthcoming parts 3, 4 and 5, The React Hooks Alternative to the Redux and Flux Patterns; Async Functional Programming using the useEffect Hook; and Gotchas of working with React hooks, respectively.

About the Author

Stefan Nagey is Co-Founder of Capbase and Dharma. In a previous life he has variously promoted motion pictures, been a diplomat and registered foreign agent, and run payment processing in the online gambling space. He variously writes about engineering and the headaches of being a startup founder in the 21st century.

--

--

Stefan Nagey
Capbase Engineering

Data geek. Capbase.com and Dharma.ai Co-Founder. Passionate about scalability, governance, cycling, and poker.