Skip to main content

ReactJS Hooks - useState

· 6 min read
Bruno Carneiro
Fundador da @TautornTech

ReactJS Hooks

Hello everyone, today I'm going to talk a little about HOOKs, how they work, and when to use them.

Reference: Pudge Dota 2


tip

 Also learn how the useEffect and use hooks work.


The Hooks feature was added to React in version 16.8, which created the possibility of using the application state and other React features without needing to create a class scope. A brief example of a component with class scope:

import React, { Component } from 'react'

class Twitter extends Component {

state = {
isLoading: true
}

constructor(props) {
super(props)
}

componentDidMount() {
window.setTimeout(() => {
this.setState({ isLoading: false })
}, 2000)
}

render() {
return (
<div>
{
isLoading ? (
<div>Loading...</div>
) : (
<div>Hello Twitter</div>
)
}
</div>
)
}
}

export default Twitter

Can be written as follows:

import React, { useEffects, useState } from 'react'

const Twitter = () => {
const [isLoading, setIsloading] = useState(true)

useEffects(() => {
window.setTimeout(() => {
setIsloading(false)
}, 2000)
}, [])

return (
<div>
{
isLoading ? (
<div>Loading...</div>
) : (
<div>Hello Twitter</div>
)
}
</div>
)
}

export default Twitter

Pretty simple, right?!

Of course the component shown above is something extremely simple and doesn't really reflect what we have in our day-to-day work.

But what I want to show is that the lifecycle and the React features remain the same, your JSX code will undergo few changes, and it's very easy to convert a component written in class to a Hooks approach and vice versa (with a few exceptions).

Remember, Hooks won't replace what you already know about React — it's just one more tool.

The motivation behind the creation of Hooks by the Facebook engineering team was:

  • It's hard to reuse logic between components;
  • Complex components can be hard to understand;
  • Classes confuse both people and machines.

Below is the complete list of native Hooks in React:

Basic Hooks:

  • useState
  • useEffect
  • useContext

Additional Hooks:

  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

But what is a Hook?

A Hook is nothing more than a function that allows you to use React features without needing to turn your component into a class.

Imagine you need to add a state to your page — like storing the return of an API so the data can be rendered on screen. Instead of creating a class using setState, you can simply use the useState Hook.

Below I'll present examples of how useState, useEffect and useContext work — the Basic Hooks and therefore the most commonly used ones.

useState

With useState it's possible to create state in the component so that changes are applied every time the state changes (React lifecycle), as shown below:

import { useState } from 'react'

function Gallery() {
const [picture, setPicture] = useState('250')

console.log("Re-render", picture)

const changeDogPicture = (dog) => setPicture(dog)

return (
<div>
<h1> Hey, look at me! </h1>
<img src={`https://placedog.net/${picture}`} alt="dog-picture" />

<h2>Click below to choose another picture</h2>
<button onClick={() => changeDogPicture(250)}>
Super Dog
</button>
<button onClick={() => changeDogPicture(100)}>
Dog 100
</button>
<button onClick={() => changeDogPicture(200)}>
Dog 200
</button>
<button onClick={() => changeDogPicture(300)}>
Dog 300
</button>
</div>
)
}

Complete code to run: Code Sandbox

useState has the following format:

const [picture, setPicture] = useState('250')

It returns two parameters: the first picture containing the current state and the second setPicture with the function to change the value of picture (thereby triggering the React lifecycle and re-rendering the component).

Notice that it's possible to initialize the state of picture with a default value useState('250'), but this is optional. It can also be initialized by simply calling the Hook const [picture, setPicture] = useState(), in which case the initial value of picture is undefined.

This way, every time a new value is provided using the setPicture method, React will understand that the application state has changed and therefore the page needs to re-render — respecting of course the element rendering rules.

Anyone who has worked with classes in React will find this is practically the same as using setState to change the state of a component.

This way, changes in a React component became much easier — it's even possible to create multiple hooks with useState.

But be careful: every time a hook (useState) fires, the component that holds the Hook's state will be re-rendered, which can generate unnecessary renders if not used wisely.

Imagine a function is executed and inside it there are several hooks changing some application state:

const [user, setUser] = useState()
const [value, setValue] = useState()
const [payments, setPayments] = useState()
const [notifcation, setNotifcation] = useState()

const handleBilling = (values) => {
setUser(values.user)
setValue(values.value)
setPayments(['values'])
setNotifcation('anything')
}

In the example above 4 renders occur on the page. Instead, we can write the result of the code above this way:

const [state, setState] = useState() // Can be any name, but I called it state to make it clearer that it's the component state. It's merely a resemblance to the name used when using class with React

const handleBilling = (values) => {
// using only one Hook and performing a single render on the page
setState({
user: values.user,
value: values.value,
payments: ['values'],
notifcation: 'anything'
})
}

But of course each case is different and the approach I used above should not be applied arbitrarily or as a requirement. Triggering more than one render in the component is not always harmful to the application and React is prepared for it. Many people are afraid of causing a memory overflow, but each case should be considered and analyzed individually.

Always take into account best practices, page performance analysis (which can be done with React Dev Tools), code readability, maintenance...

There's no hard rule, but always analyze what you're developing :)

Well, this is a small example of the useState Hook in action. Below are some references where you can find examples with the other Hooks.

To learn about useEffect

info

I'll soon update this page with useContext examples

References:

ReactJS - Hooks Reference Awesome React Hooks Enmascript