React 18 hooks tutorial with examples

React 18 hooks tutorial with examples

The purpose of this tutorial is to teach you about React Hooks and show you some examples of how to use the useState() hook for adding state and the 'useEffect()' hook for executing side effects in your functional components.

This is a new feature introduced by the React team lately. React Hooks are an enhancement of the React framework. From version 16.7 forward, it is integrated in React.

At this time, React 18 is already available which provides more new features to the most popular library for building user interfaces with JavaScript. You also read how to upgrade your app to React 18.

React Hooks Tutorial

In this article, we'll learn how to upgrade our previous project from using class components, life-cycle methods, and the state object to using function components and React Hooks instead.

Prerequisites

You need to have:

  • Node.js 6+, npm v5.2+ and create-react-app for running the React app,
  • Basic knowledge of ES6.

Introduction to React Hooks

Before we migrate our example project to functional components and React Hooks, let's first define hooks and why we need them.

So, what's the big deal with React hooks? What can they provide you?

Simply put, if you need to leverage React features like state and life-cycle events/methods (which is usually the case), you must use or transition to ES6 classes by extending React.Component. That is no longer the case; using hooks, you may now utilize those often required functionalities in your functional components.

What is A React Hook?

React 18 is currently the most popular and widely used UI library on the planet. The team is continually striving to enhance both the library's efficiency and the developer experience by introducing new features that make developers' jobs simpler.

A React Hook is a new feature to use the React.Component features in a functional component.

These features include:

  • The state object,
  • Life-cycle events like componentWillMount, componentDidMount, componentWillUpdate and componentDidUpdate etc.
  • The context,
  • The refs etc.

Components based on classes are still useful. It's simply that you now have more alternatives for doing the same thing, and it's up to you whether to utilize classes or functions to develop your React applications without being constrained by a lack of functionality with either option.

They have elegant names, but they are straightforward ideas to comprehend, much like the other React principles. Hooks are similar to functions in that they enable developers to "hook into" React state and life-cycle operations from functional components.

React Hooks are not accessible in class-based components, but they enable you to utilize React without the need for JavaScript classes. If you want to utilize functions rather than classes (as is advised in JavaScript), you can just begin utilizing Hooks without having to worry about moving your entire project to classes.

Hooks enable you to use “class-features” In React by providing a set of built-in functions such as:

  • The useState() hook for using states from function components,
  • The useEffect() hook for performing side effects from function components (It's equivalent to life-cycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount in React classes),
  • The useContext() hook for subscribing to React Context from a function component,

  • The useReducer() hook for managing the state of components with a reducer

  • useRef for React Refs,

  • The useCallback hook for callbacks,

  • The useMemo hook for memoized values,

  • The useImperativeMethods hook for imperative methods,

  • The useMutationEffect hook for mutation effects,

  • The useLayoutEffect hook for layout effects.

You can also create your custom Hooks to re-use any stateful behavior between different components.

Note: React Hooks lets you have stateful functional components.

React Hooks are typical JavaScript functions, with the exception that they need to obey some rules:

  • React Hooks need to be used at the top level i.e not inside nested functions or other JS constructs like loops or if conditions etc.
  • React Hooks need to be used in functional components not in regular JavaScript functions. You can also call built-in Hooks from your custom Hooks

The React team provides a linter plugin that can be used by developers to make sure these rules are respected so the React Hooks can work as expected in your app.

Example Accessing State in Functions with useState()

Now that we have seen some theory about React Hooks. Let’s see a simple example of a stateful function component with the useState() hook. Let’s start with a simple stateless function component that we are familiar with.

This a simple React app with one ContactPage function component:

import React from 'react';
import { render } from 'react-dom';

function ContactPage(props) {
   return (
    <div>
     <h1>Contact Page</h1>
    </div>);
}

render(
  <ContactPage />,
  document.querySelector('#root'));

In the old React, If we want to keep or work with any state in this component we'll need to convert it into a class component. For example, let's say we need to use an email variable in our component. This is what we'll have to do:

class ContactPage extends React.Component {
  state = {
    email: '[email protected]'
  }


  render() {
    return (
     <div>
       <h1>Contact Page</h1>
        <p>My email is {this.state.email}</p>
       </div>
    );
  }
}

We rewrite our component to use a class instead of a function so we can be able to use the state object.

Now, thanks to React Hooks we can simply use this alternative code without re-writing you component:

import React,  { useState }  from  'react';
import { render } from 'react-dom';

function ContactPage(props) {
   const  [email, setEmail]  =  useState('[email protected]');
   return (
    <div>
       <h1>Contact Page</h1>
        <p>My email is {this.state.email}</p>     
    </div>);
}

This is our regular function but it now has a state thanks to the useState() hook function.

Note: Hook functions start with the use word which is another rule of Hooks.

The useState() hook takes an initial state and returns an array with two elements:

  • The current state,
  • and a function to set the state.

In our example, we pass in the [email protected] string as initial state and we use Array destructing assignment to grab variables and rename them properly.

We can access the current piece of state using email and the function to set the state using setEmail().

The useState() hook provides us with two variables that we need to rename with proper names. To be able to rename these variables properly, you need to know these two things:

  • The first element of the returned array presents the value which equivalent to this.state in the class components.
  • The second element is a function to set that value which is equivalent to this.setState() in classes.

The state can be any valid JavaScript object.

Example using The Effect Hook in React 18

Now that we have seen the State Hook with example and understand why we need to use it - i.e to have state in React 18 functional components. Let's see an example using the Effect Hook to be able to perform side effects in our functional components without resorting to using life-cycle methods which are only available in class components.

Note: Effect Hooks are equivalent to componentDidMount, componentDidUpdate and componentWillUnmount life-cycle methods combined.

Side effects are common operations that most web applications need to perform, such as:

  • Fetching and consuming data from a server API,
  • Updating the DOM,
  • Subscribing to Observables etc.

Note: Effect Hooks will run after every render, including the first render.

Here is an example:

import React, { useState } from 'react';

function Customers() {
  const [customers, setCustomers] = useState([]);

  useEffect(() => {
    fetch('127.0.0.1:8000/customers')
      .then(response => response.json())
      .then(data => {
        setCustomers(data); // set customers in state
      });
  }, []); 
}

We first use the useState() hook with an empty array for the initial state to create a customers state variable.

Next, we'll use the useFetch() hook to run a side effect which is sending a request, using the Fetch API, to an API endpoint that returns a list of customers.

We finally use the setCustomers() method to assign the returned data to the customers state variable.

Conclusion

You can mix and match different sorts of hooks or use the same hook several times in your application without issue. In fact, in most projects, you'll need to use them both to fully use functional components without having to rely on any functionality in class-based components.