React Hooks: useState

Deinyefa
3 min readFeb 24, 2020

Before React 16.8, updating state required your component to be class-based. This meant that if you started your component as a “stateless”, or functional component and then realized that you needed state, you’d need to convert your component to be class-based.

Classical Component Example

With the introduction of React Hooks, this is no longer the case.

The useState hook takes an optional initial state value, and returns two things; the value and a function to update that value. So,

this.state = { count: 0 };

becomes

const [count, updateCount] = React.useState(0);

Notice that this is a familiar JavaScript syntax. The values returned from useState are set as variables (constant variables, lol) with array destructuring; in this case count is a number (implicitly, because it was initialized with the value 0), while updateCount is a function that would be used to update count.

The example below updates a cart and displays items inside the cart as it is added.

Using useState

Above, there are 2 state hooks in use; holds an object of an item and that item’s count, while the other holds all items that have ever been added.

Form input handles updating the item by calling updateItem on onChange, while the input value is set by directly passing the item constant — item.name for the item name input and item.count for the amount.

On the other hand, submitting the form triggers the logic to add this new item object to an object, that can then be displayed back to the user.

updateCart([ ...cart, { name, count } ])

...cart spreads the cart array into this new array because we want to immutably update its value.

Notice that when I called handleUpdateCart, I passed the item object, but then where I declared, I destructured the object, exposing the keys to be used directly in the function, instead of having to access them by going item.name or item.count. Cool.

Back to updateCart, { name, count } is an example of Object Initialization From Variables. This is another JavaScript ES6 shorthand that allows me to set object values because I’m passing a variable that has the same name as the key whose value I’m trying to set.

To display the cart items as a list, cart is represented as an array, so we have access to JavaScript iterable functions like map.

const cartHTML = cart.map((item, idx) => (
<tr key={idx}>
<td>{item.name}</td>
<td>{item.count}</td>
</tr>
));

cartHTML loops through cart and returns an object that is represented as a table row with cells. Note that in this case, we could also use object destructuring to expand item to { name, count }.

const cartHTML = cart.map(({ name, count }, idx) => (
<tr key={idx}>
<td>{name}</td>
<td>{count}</td>
</tr>
));

If you’re familiar with the class-based implementation of updating state, you might remember that state could also be updated based on what it previously was:

this.setState(prevState => {
return { count: prevState.count + 1 }
});

This still works with hooks:

Functional updates

--

--

Deinyefa

UX Engineer ⋅ JavaScript ⋅ Hooked on ReactJS