React hooks let us use ("hook in to") React features such as state and lifecycle methods in function components. Before the hooks API was introduced to React, if we wanted a component to maintain some state, we would have to write it as a class component.
While it is important to learn why and how things function in the language you are writing in, classes can initially create an unnecessary barrier to initial productivity or understanding of other concepts. For example, as a new react developer, you may gain an understanding of how state and events work in react, but then get tripped up by a bug because you don't have a solid understanding of how the this
keyword works.
In this post we will take a look at how the useState hook works to allow us to make function components stateful.
Using the useState Hook
In order to use the useState hook we first need to import it. After we import it we can use it to create some local state within a function component.
import React, { useState } from 'react';
function Example() {
...
}
useState
takes one argument and returns a pair of values. The first in the pair of values is the current state value, and the second is a function that lets you update the value. React preserves this state between renders.
In the example below useState
returns a state variable category
and a function setCategory
that we can use to update the value of the category variable. The argument passed in is whatever you want the initial state to be and will only be used for the initial render. In the example we pass in the string "Clothing"
as the argument.
import React, { useState } from 'react';
function Example() {
const [category, setCategory] = useState("Clothing")
return (
<p>{category}</p>
)
}
Unlike in class components, when we use useState
, the value passed in as the argument does not have to be an object. We can pass in a string, a number, an object, null etc. We can also use useState
multiple times to create different state variables. The function returned by useState
is similar conceptually to calling this.setState
in a class component. However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it.
So we created some local state, how do we use and update it in our code?
In the example below we have a function component ProductListing
that has two calls to useState. Since the first item in the pair useState returns is just a variable with the initial value we provided as the argument, we can use this variable directly in our components jsx without having to write something like this.state.category
as we do in class components.
import React, { useState } from 'react';
function ProductListing() {
const [category, setCategory] = useState("Clothing")
const [product, setProduct] = useState({"id" : 1, "name": "jeans"});
return (
<div>
<h1>{category}</h1>
<p>{product.name}</p>
</div>
);
}
Lets add an input that allows us to type in a category and update our category state variable. Our input has an event handler handleCategoryChange
that uses the setCategory
function to update the category state variable with the current value of the input. As we type we will see the category being updated in real time.
import React, { useState } from 'react';
function ProductListing() {
const [category, setCategory] = useState("Clothing")
const [product, setProduct] = useState({"id" : 1, "name": "jeans"});
const handleCategoryChange = (e) => {
setCategory(e.target.value)
}
return (
<div>
<input onChange={handleCategoryChange}/>
<h1>{category}</h1>
<p>{product.name}</p>
</div>
);
}
However, i would like to reiterate that updating a state variable always replaces it instead of merging it as this.setState
in a class does. If we wanted to update our product state variable and called setProduct with a different product object, we would be replacing the whole product object and not merging it with the previous one. This is a big part of the reason why we can have many different state variables. It is recommended to split state into multiple state variables based on which values tend to change together. You can read more about ways to think about this in the official react docs here.
Hopefully you have come away with a better understanding of how the useState hook works to allow you to add local state to your function components! I would recommend reading through the react docs on the useState hook for a deeper dive!
If you have any questions, comments, or feedback - please let me know. Follow for new weekly posts about JavaScript, React, Python, and Django!
Top comments (3)
React hooks has made life much more easier. :)
Great tutorial.
Thank you! I'm working on a project now using hooks and really enjoying it :)
Where did you learn hooks from ?
Currently net ninja video has been really helpful to me. :)