Table of contents
Welcome to my blog where we explore the world of React hooks! Today, we'll be taking a closer look at the useState hook - a fundamental hook that every React developer should be familiar with. useState is a built-in hook in React that allows us to add state to our functional components. It's a simple and intuitive hook that makes managing state in our components a breeze. In this article, we'll dive into the nitty-gritty details of useState, including how to use it, what it does, and why it's so powerful. So, let's get started!
First, Events!
To gain a better understanding of working with state in React, it's important to first discuss the topic of events. Whenever a user interacts with a page, numerous events are triggered as a response. The browser behaves almost like a relentless detective, meticulously tracking every action taken by the user.
In the realm of building dynamic web applications, events hold great significance. They serve as the trigger points for state changes. For instance, the "X" button click dismisses a prompt, while a form submission may show a loading spinner. It's crucial to listen attentively to these events and appropriately respond with the necessary state changes to enhance the user experience.
In order to respond to an event, we need to listen for it. JavaScript provides a built-in way to do this, with the addEventListener
method:
const button = document.querySelector('.btn');
function doSomething() {
// Stuff here
}
button.addEventListener('click', doSomething);
Here we have an example of event handling code. We've specified a particular event, in this case, "clicks," that we want to listen for, and we've targeted a specific element with the CSS class .btn
. We've defined a function doSomething
to handle this event. When the user clicks on this button, our handler function will be executed, giving us the opportunity to perform some actions in response.
useState Intro
We can start by looking into a really basic "counter" demo
import React from 'react';
function Counter() {
const [count, setCount] = React.useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Value: {count}
</button>
);
}
export default Counter;
This code snippet may seem overwhelming, but let's take a closer look at it.
The objective is to keep track of how many times the user has clicked the button. When we have values that change "dynamically", we need to incorporate React state. State is specifically utilized for values that undergo modifications over time.
To create a state variable, we use the useState
function. This function takes a single argument: the initial value. In this case, that value initializes to 0
. This value is chosen because when the page first loads, we've clicked the button 0 times.
useState
is a hook. A hook is a special type of function that allows us to "hook into" React internals. We'll learn much more about hooks later in this course.
The useState
hook returns an array containing two items:
The current value of the state variable. We've decided to call it
count
.A function we can use to update the state variable. We named it
setCount
.
But how do we Name it?
When we create a state variable, we can name the two variables whatever we want. For example, this is equally valid:
const [hello, world] = React.useState(0);
That said, it's familiar to follow the “x, setX” convention:
const [user, setUser] = React.useState();
const [errorMessage, setErrorMessage] = React.useState();
const [dropdown, setDropdown] = React.useState();
Let's dive into the destructuring syntax used in this code. The first variable is assigned the name of the state variable we're tracking, while the second variable is assigned a function prefixed with "set", which is used to update the value of that variable. This function is commonly known as a "setter function" since it sets the new value of the state variable.
Intial Value
React state variables can be given an initial value:
const [count, setCount] = React.useState(3);
console.log(count); // 3
We can also provide a function. React will call this function on the very first render to calculate the initial value:
const [count, setCount] = React.useState(() => {
return 1 + 1;
});
console.log(count); // 2
This secondary form can occasionally be useful if we need to do an expensive operation to calculate the initial value. For example, reading from localStorage:
const [count, setCount] = React.useState(() => { return window.localStorage.getItem('saved-count');});
The benefit here is that we're only doing the expensive work (reading from localStorage) once, on the initial render, rather than doing it on every single render.