React Hooks useState and useEffect Examples

by Didin J. on Dec 04, 2019 React Hooks useState and useEffect Examples

The real-world examples of React Hooks useState and useEffect in a React.js Web application

In this React.js tutorial, we will show you the real-world examples of React Hooks useState and useEffect in a React.js Web application. Previously, we have written a tutorial about the introduction of React Hooks that use in the React.js app. Now, with these examples you will learn more deeply about a few essential React Hooks useState and useEffect.

Table of Contents:

The following tools, frameworks, libraries, and modules are required for this tutorial:

  1. Node.js (with NPM or Yarn)
  2. React.js (min. version 16.8)
  3. Node-Express REST API
  4. Terminal or Node Command Line
  5. IDE or Text Editor (We are using Visual Studio Code)

You can watch the video tutorial on our YouTube channel here. Please, like, share, comment, and subscribe to this channel to make more tutorials about React.js.


Preparation

We need to prepare the environment for creating React.js application from the scratch, we assume you don't have any tools or frameworks installed on your computer. The first thing to do is install Node.js with NPM or Yarn. Just download the installer from official download page https://nodejs.org, choose recommended version for your OS. Install to your computer by following the install wizard. After Node.js installation finished, open your terminal (Mac OS/Linux) or Node command line (Windows) then check the installed Node.js and NPM.

node -v
v10.15.1
npm -v
6.13.1

If you plan to use Yarn, install it from the Terminal. On our Mac OS, we type this command.

brew install yarn

You can choose your desired installation method for your OS, you find the guide on the Yarn site. To check the installed yarn version, type this command.

yarn -v
1.19.2

Next, we will use the create-react-app tool. The create-react-app is a tool to create a React.js app from the command line or CLI. So you don’t need to install or configure tools like Webpack or Babel because they are preconfigured and hidden so that you can focus on the code. Type this command to install it.

sudo npm install -g create-react-app

Now, we can create a new React.js app using that tool.

create-react-app react-hooks-use

This command will create a new React app with the name `react-hooks-use` and this process can take minutes because all dependencies and modules also installing automatically. Next, go to the newly created app folder.

cd ./react-hooks-use

Open the project in your IDE or text editor and see the content of package.json.

"dependencies": {
  "react": "^16.12.0",
  "react-dom": "^16.12.0",
  "react-scripts": "3.2.0"
},

That React version is the version that already uses React Hooks as default. Now, `src/App.js` doesn't use class anymore. For sanitation, run this React app for the first time by type this command.

yarn start

And here' we go the latest React.js application that uses React Hooks with the same initial home page.

React Hooks useState and useEffect Examples - React Home

Next, we need to add the required component or page for each example. For that, add these directories and files inside the src directory.

mkdir src/hooks-state
mkdir src/hooks-effect
touch src/hooks-state/BasicState.js
touch src/hooks-state/MultipleState.js
touch src/hooks-effect/BasicEffect.js
touch src/hooks-effect/FetchEffect.js
touch src/hooks-effect/AxiosEffect.js
touch src/hooks-effect/ListenerEffect.js

Next, add the react-router-dom to make routing and navigation for these examples.

yarn add react-router-dom

Next, open and edit `src/index.js` then add these imports of Router and Route (react-router-dom) and all created components before the `./index.css` import.

import { BrowserRouter as Router, Route } from 'react-router-dom';
import BasicState from './hooks-state/BasicState';
import MultipleState from './hooks-state/MultipleState';
import BasicEffect from './hooks-effect/BasicEffect';
import FetchEffect from './hooks-effect/FetchEffect';
import AxiosEffect from './hooks-effect/AxiosEffect';
import ListenerEffect from './hooks-effect/ListenerEffect';

Next, add <Router> to the React.DOM render.

ReactDOM.render(
    <Router>
        <div>
            <Route render ={()=> < App />} path="/" />
            <Route render ={()=> < BasicState />} path="/hooks-state/basic-state" />
            <Route render ={()=> < MultipleState />} path="/hooks-state/multiple-state" />
            <Route render ={()=> < BasicEffect />} path="/hooks-effect/basic-effect" />
            <Route render ={()=> < FetchEffect />} path="/hooks-effect/fetch-effect" />
            <Route render ={()=> < AxiosEffect />} path="/hooks-effect/axios-effect" />
            <Route render ={()=> < ListenerEffect />} path="/hooks-effect/listener-effect" />
        </div>
    </Router>, document.getElementById('root'));

Next, we will create navigation for all React Hooks useState and useState examples. Open and edit `src/App.js` then replace all "return" content with these.

return (
  <div className="App">
    <h2>React Hooks Examples</h2>
    <h3>useState Examples:</h3>
    <p><a href="/hooks-state/basic-state">Basic useState Example</a></p>
    <p><a href="/hooks-state/multiple-state">Multiple useState Example</a></p>
    <h3>useEffect Examples:</h3>
    <p><a href="/hooks-effect/basic-effect">Basic useEffect Example</a></p>
    <p><a href="/hooks-effect/fetch-effect">Fetch useEffect Example</a></p>
    <p><a href="/hooks-effect/axios-effect">Axios useEffect Example</a></p>
    <p><a href="/hooks-effect/listener-effect">Listener useEffect Example</a></p>
    <p><a href="/hooks-effect/resize-effect">Resize useEffect Example</a></p>
  </div>
);

Next, make all components file have an exported function name same as the file name as an example below.

import '../App.css';

function BasicState() {

  return (
    <div className="App">
    </div>
  );
}

export default BasicState;


React Hooks useState Examples

Before seeing the example, we try to make a little understanding of the React Hooks useState formula. It just simply like this line.

const [state, setState] = useState(initialState);

Which "state" is a variable, "setState" if a function that can change the variable, and "initialState" is an initial value of the variable.

Basic useState Example

Next, we need to implement the React Hooks basic useState. Open and edit `src/hooks-state/BasicState.js` then add useState to the `react` import.

import React, { useState } from 'react';

We will declare a variable of the string that has an initial value.

const [title, setTitle] = useState('Getting Started learning a React Hooks');

In this basic useState usage, we will put the "setTitle" that change the "title" value as a button action. Add/replace these lines to the React template to add a text and a button.

return (
  <div className="App">
    <h2>{title}</h2>
    <button onClick={() => setTitle('React Hooks in My Learning Path')}>
      Change Title
    </button>
  </div>
);

Multiple useState Example

This example is the multiple "useState" with different data types. Open and edit `src/hooks-state/MultipleState.js` then add useState to the `react` import.

import React, { useState } from 'react';

Add these multiple constant variables.

const [title, setTitle] = useState('Getting Started learning a React Hooks');
const [year, setYear] = useState(2019);
const [emails, setEmail] = useState([
  {name: 'my name', email: '[email protected]'},
  {name: 'my second name',email: '[email protected]'},
  {name: 'my third name',email: '[email protected]'},
  {name: 'my alias name',email: '[email protected]'}
]);

Replace the "return" content with these.

return (
  <div className="App">
    <h2>{title}</h2>
    <h2>{year}</h2>
    <dl>
      {emails.map((item, idx) => (
        <dd>{item.name}, {item.email}</dd>
      ))}
    </dl>
    <button onClick={() => {
      setTitle('Another React Hooks Book');
      setYear(2020);
      setEmail([
        {name: 'Ian Rush', email: '[email protected]'},
        {name: 'Roberto Baggio',email: '[email protected]'},
        {name: 'Thierry Hendry',email: '[email protected]'},
        {name: 'David Seaman',email: '[email protected]'}
      ]);
    }}>
      Change Title
    </button>
  </div>
);


React Hooks useEffect Examples

React Hooks useEffect is a single function that similar to componentDidMount, componentDidUpdate, and componentWillUnmount in React classes. We will show you an example of the useEffect in a real React application.

Basic useEffect Example

This basic useEffect example just changes the title when the component is loaded. Open and edit `src/hooks-effect/BasicEffect.js` then add this import of useState and useEffect.

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

Add a required constant variable that uses useState.

const [title, setTitle] = useState('React Hooks at a Glance');
const [year, setYear] = useState(2019);

Add this useEffect function before the `return` template.

useEffect(() => {
  setTitle(`The new articles of ${year}`);
});

Change the `return` content with these.

return (
  <div className="App">
    <h2>{title}</h2>
  </div>
);

Fetch useEffect Example

This example fetches data from the REST API you can run our Node-Express REST API and MongoDB server in your machine to implementing this example. Open and edit `src/hooks-effect/FetchEffect.js` then add this import of useState and useEffect.

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

Add a required constant variable that use useState.

const [product, setProduct] = useState(null);
const [url, setState] = useState(`http://localhost:3000/api/v1/products`);

Next, we will implement useEffect with a cleaning-up effect feature by adding an AbortController method at the useEffect return. Add this useEffect function after the constant variable.

useEffect(() => {

  let abortController = new AbortController();

  const loadProduct = async () => {
    try {
      const response = await fetch(url, { signal: abortController.signal });
      const data = await response.json();
      console.log(`Data fetched: ${data}`);
      setProduct(data);
    } catch (error) {
      console.log(`Error fetch data: ${error}`);
      throw error;
    }
  };

  loadProduct();

  return () => {
    console.log("Cancel fetch: abort");
    abortController.abort();
  };
}, [url]);

If you want to implement conditionally firing an effect, just change the end of the useEffect function to this.

useEffect(() => {
  ...
}, [product]);

Next, add a loading indicator before implementing the view template.

if (!product) {
  return <div className="App">Loading...</div>;
}

Modify the return to display the loaded data.

return (
  <div className="App">
    {product.map((item, idx) => (
      <p>{item.prod_name}</p>
    ))}
  </div>
);


Axios useEffect Example

This example same as the previous fetch example except we are using the Axios library to consume the REST API. First, we need to install that library by type this command in the terminal.

yarn add axios

Next, open and edit `src/hooks-effect/AxiosEffect.js` then add these imports of useState, useEffect, and Axios.

import React, { useState, useEffect } from 'react';
import Axios from "axios";

Add a required constant variable that uses useState.

const [product, setProduct] = useState(null);
const [url, setState] = useState(`http://localhost:3000/api/v1/products`);

Next, we will implement useEffect with a cleaning-up effect feature by adding an `Axios.CancelToken.source()` cancel method at the useEffect return. Add this useEffect function after the constant variable.

useEffect(() => {
  let source = Axios.CancelToken.source();

  const loadProduct = async () => {
    try {
      const response = await Axios.get(url, {
        cancelToken: source.token
      });
      console.log(response);
      setProduct(response.data);
    } catch (error) {
      if (Axios.isCancel(error)) {
        console.log("Cancel axios data source on error");
      } else {
        throw error;
      }
    }
  };

  loadProduct();

  return () => {
    console.log("Cancel axios data source");
    source.cancel();
  };
}, [url]);

Next, add a loading indicator before implementing the view template.

if (!product) {
  return <div className="App">Loading...</div>;
}

Modify the return to display the loaded data.

return (
  <div className="App">
    {product.map((item, idx) => (
      <p>{item.prod_name}</p>
    ))}
  </div>
);

Listener useEffect Example

This example of React Hook's useEffect is firing an effect based on Javascript DOM event listener. Right now, we will use the `click` event lister for the windows or screen element. Open and edit `src/app/hooks-effect/ListenerEffect.js` then add this import of useEffect.

import React, { useEffect } from 'react';

Next, we will implement the useEffect that firing by click event listener.

useEffect(() => {
  const listener = () => {
    console.log(`The screen is clicked`);
  };
  window.addEventListener("click", listener);

  return () => {
    window.removeEventListener("click", listener);
  };
}, []);

Next, modify the return to this HTML template.

return (
  <div className="App">
    <h4>Click the screen to listen the click event</h4>
  </div>
);


Run and Test the React Hooks useState and useEffect Examples

To run this React Hooks useState and useEffect examples, we need to run MongoDB server and Node-Express REST API first in another terminal tabs. Next, run this React Hooks example using custom port by type this command.

PORT=8080 yarn start

Now, the React Hooks useState and useEffect Examples run using Port 8080 that different from the Node-Express server. You can check the implementation of these examples one by one from this React home page.

React Hooks useState and useEffect Examples - React Hooks state and effect

That it's, the React Hooks useState and useEffect Examples. You can find the full source codes from our GitHub.

That just the basic. If you need more deep learning about MERN Stack, React.js or React Native you can take the following cheap course:

Thanks!