React.js: Hooks, useState, useEffect

January 31, 2021

Table of Contents


React.js Hooks, useState, and useEffect

React.js Hooks are a collection of functions to update state variables, detect events, and other React.js features.
useState and useEffect are two of these functions.


useState

useState returns an array with two elements, the first one is a variable, and the second is a function.
• The first one is a variable that can be used to store data for the component.
• The second one is a function that will be used to update the values stored on the state variable.


In this example we use the useState hook to return a "state" variable that will store the text entered on an html input field. We added a onChange event that will pass the entered value to a function, which will call the setState function.


import React, { useState } from "react";

function Sample1() {
    const [state, setState] = useState('');

    function handleChange(event) {
        const value = event.target.value;
        setState(value);
    }

    return (
        <>
            <h1>Sample 1</h1>
            <input type="text" value={state} onChange={handleChange} />
            <input type="button" value="Click me" onClick={() => alert(`The text entered is ${state}`)} />
        </>
    );
}

function App() {
    return (
        <>
            <Sample1 />
        </>
    );
}

export default App;

This example shows that the returned values of the useState hook do not need to have to be named state, setTitle. In this example we named them as title, setTitle.


import React, { useState } from "react";

function Sample2() {
    const [title, setTitle] = useState('');

    function handleChange(event) {
        const title = event.target.value;
        setTitle(title);
    }

    return (
        <>
            <h1>Sample 2</h1>
            <div>Enter Title</div>
            <input type="text" value={title} onChange={handleChange} />
            <input type="button" value="Click me" onClick={() => alert(`The title is ${title}`)} />
        </>
    );
}

function App() {
    return (
        <>
            <Sample2 />
        </>
    );
}

export default App;

The variable returned by the useState hook can be of any type, an scalar value as shown on the examples above, or an object as shown in this example.


import React, { useState } from "react";

function Sample3() {
    const [state, setState] = useState({
        email: '',
        subject: ''
    });

    // We use the same handler for all the fields
    function handleChange(event) {
        // Get the name and value of the field
        const {name, value} = event.target;
        // Only update the field that has been changed
        setState(prevState => ({...prevState, [name]: value}));
    }

    return (
        <>
            <h1>Sample 3</h1>
            <div>
                <label>Email</label><br/>
                <input type="text" name="email" value={state.email} onChange={handleChange} />
            </div>
            <div>
                <label>Subject</label><br/>
                <input type="text" name="subject" value={state.subject} onChange={handleChange} />
            </div>
            <div>
                <input type="button" value="Click me" onClick={
                    () => alert(`The email is ${state.email}, and the subject is "${state.subject}"`)
                } />
            </div>
        </>
    );
}

function App() {
    return (
        <>
            <Sample3 />
        </>
    );
}

export default App;

useEffect

The useEffect hook is used to run code after the Component has been rendered, and/or every time that the Component is updated.


The useEffect hook method has two parameters,
• The first parameter is a callback function.
• The second is an optional parameter where you specify an array of variables.


In this example the callback function will be executed every time the input field is changed.


import React, { useState, useEffect } from "react";

function Sample1() {
    const [state, setState] = useState('');

    useEffect(() => {
        console.log(`Any field has been updated`);
    }); 

    return (
        <>
            <h1>Sample 1</h1>
            <input type="text" value={state} onChange={(event) => setState(event.target.value)} />
        </>
    );
}

function App() {
    return (
        <>
            <Sample1 />
        </>
    );
}

export default App;

In this example we have defined two calls to the useEffect hook.

On the first one, we used an empty array as the second parameter. This will cause that the callback function will be invoked only once.

On the second call, we use an array with the "state" value. This will cause that the callback function will be invoked only when the "state" field is changed.


import React, { useState, useEffect } from "react";

function Sample2() {
    const [state, setState] = useState('');

    useEffect(() => {
        console.log(`This code is executed only the first time the component is rendered`);
    }, []);

    useEffect(() => {
        console.log(`Only the "state" field has been updated`);
    }, [state]);

    return (
        <>
            <h1>Sample 2</h1>
            <input type="text" value={state} onChange={(event) => setState(event.target.value)} />
        </>
    );
}

function App() {
    return (
        <>
            <Sample2 />
        </>
    );
}

export default App;

A feature of the useEffect hook is that if the callback function has defined a return function, it will be executed to do a cleanup of the previous rendering of the Component, when the Component is about to be rendered because of an update.

In this example we have defined a "my_cleanup_func" return function. You can name this function with any name you want.


import React, { useState, useEffect } from "react";

function Sample3() {
    const [state, setState] = useState('');

    useEffect(() => {
        console.log(`Any field has been updated`);
        return function my_cleanup_func() {
            console.log('Cleaning up');   
        };
    }); 

    return (
        <>
            <h1>Sample 3</h1>
            <input type="text" value={state} onChange={(event) => setState(event.target.value)} />
        </>
    );
}

function App() {
    return (
        <>
            <Sample3 />
        </>
    );
}

export default App;

Live Demo

See a live demo of the useState sample code on StackBlitz here.

See a live demo of the useEffect sample code on StackBlitz here.