ARTICLE

Managing Component State with the useState Hook

From React Hooks in Action by John Larsen

Figure 1. When you change a value in a component, React should update the UI.

A bookings manager

Figure 2. The Bookables component displays a list of bookable items filtered by group and the details of the selected bookable.
git checkout 301-hard-coded

Adding a database file

{
"bookables": [ #A
{
"id": 1,
"group": "Rooms",
"title": "Meeting Room",
"notes": "The one with the big table and interactive screen."
},
{ #B
"id": 2, #B
"group": "Rooms", #B
"title": "Lecture Hall", #B
"notes": "For more formal 'sage-on-the-stage' presentations" #B
}, #B
{
"id": 3,
"group": "Rooms",
"title": "Games Room",
"notes": "Table tennis, table football, pinball!"
},
{
"id": 4, #C
"group": "Rooms", #C
"title": "Lounge", #C
"notes": "A relaxing place to hang out." #C
},
{
"id": 5,
"group": "Kit",
"title": "Projector",
"notes": "Portable but powerful. Keep it with the case."
},
{
"id": 6,
"group": "Kit",
"title": "Wireless mics",
"notes": "Really handy but don't forget to switch them off."
}
]
}

Storing, using and setting values with useState

Calling useState returns a value and an updater function

Figure 3. Rather than changing a value directly, we call an updater function. The updater function changes the value and React updates the display with the recalculated UI from the component.
Figure 4. The useState function returns an array with two elements: a value and an updater function.
const selectedRoomArray = useState();                           #A

const selectedRoom = selectedRoomArray[0]; #B

const setSelectedRoom = selectedRoomArray[1]; #C
const [ selectedRoom, setSelectedRoom ] = useState();
const [ myRoom, updateMyRoom ] = useState();
Figure 5. When the component first runs, React assigns the initial value you pass to useState to the ‘selected’ variable.
const [ selected, setSelected ] = useState("Lecture Hall");
Figure 6. The Bookables component with Lecture Hall selected.
import React, { useState } from "react";                       #A
import {bookables} from "../db.json";

export default function Bookables () {
const group = "Rooms";
const bookablesInGroup = bookables.filter(b => b.group === group);
const [ bookableIndex, setBookableIndex ] = useState(1); #B

return (
<ul className="bookables">
{bookablesInGroup.map((b, i) => (
<li
key={b.title}
className={i === bookableIndex ? "selected" : null} #C
onClick={() => setBookableIndex(i)} #D
>
{b.title}
</li>
))}
</ul>
);
}

Calling the updater function replaces the previous state value

class Bookables extends React.Component {
constructor (props) {
super(props);

this.state = {
bookableIndex: 1,
group: "Rooms"
};
}
}
handleClick (index) {
this.setState({
bookableIndex: index
});
}
Figure 7. In a class component, calling the updater function (this.setState) merges the new properties with the existing state object.

The function component approach

const [bookableIndex, setBookableIndex] = useState(1);

setBookableIndex(3); // React replaces the value 1 with 3.
function Bookables () {
const [state, setState] = useState({
bookableIndex: 1,
group: "Rooms"
});
}
function handleClick (index) {
setState({
bookableIndex: index
});
}
Figure 8. In a function component, calling an updater function (returned by useState) replaces the old state value with whatever you pass to the updater function.
function handleClick (index) {
setState({
...state,
bookableIndex: index
});
}
function handleClick (index) {
setState(state => {
return {
...state,
bookableIndex: index
};
);
}

Reviewing some function component concepts

  • Components are functions that accept props and return a description of their UI.
  • React invokes the components. As functions, the components run their code, and end.
  • Some variables may persist within closures created by event handlers. Others are destroyed when the function ends.
  • We can use hooks to ask React to manage values for us. React can pass components the latest values and updater functions for those values.
  • By using the updater functions, we let React know of changing values. It can re-run the components to get the latest description of the UI.

Component

Initial value

Updater function

Event handler

UI

Figure 9. Stepping through the key moments when using useState

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Manning Publications

Follow Manning Publications on Medium for free content and exclusive discounts.