Back to Course

Learn React

0% Complete
0/0 Steps
Lesson 11 of 32
In Progress

Introduction to React Hooks

React Hooks are a new feature in React 16.8 that allow you to use state and other React features without writing a class component. They were introduced in React to address a few problems with the current way of writing components, including the difficulty of reusing logic between components, the complexity of managing state and side effects, and the verbosity of writing class-based components.

Hooks are a way to reuse stateful logic, not state itself. They don’t replace your knowledge of React concepts. Instead, Hooks provide a way to use them in functional components.

In this article, we will explore the various Hooks that are available in React and learn how to use them to build efficient and scalable React applications.

What are React Hooks?

React Hooks are functions that allow you to use state and other React features in functional components. They were introduced in React 16.8 as a way to address the problems with the current way of writing components and to make it easier to reuse logic between components.

Hooks are a way to reuse stateful logic, not state itself. They don’t replace your knowledge of React concepts. Instead, Hooks provide a way to use them in functional components.

There are two types of Hooks:

  • State Hooks: These Hooks allow you to use state in functional components.
  • Effect Hooks: These Hooks allow you to perform side effects in functional components.

Why use React Hooks?

There are a few problems with the current way of writing components in React that Hooks were introduced to address:

  • Reusing logic between components is difficult: In the current way of writing components, it is difficult to reuse logic between components because each component is a standalone unit. This means that if you want to reuse logic between components, you need to either extract it into a separate utility function or create a higher-order component. Both of these approaches have their own limitations and can make the code difficult to understand.
  • Managing state and side effects is complex: Managing state and side effects in React can be complex because you need to use a class component and write code in the constructor, componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods to handle state and side effects. This can make the code verbose and difficult to understand.
  • Class-based components are verbose: Class-based components are verbose because they require you to write a lot of boilerplate code, such as the constructor, render method, and the this keyword. This can make the code difficult to read and understand.

Hooks were introduced to address these problems and make it easier to reuse logic between components, manage state and side effects, and write components that are easy to read and understand.

How to use React Hooks

To use React Hooks, you need to know the following two Hooks:

  • useState: This Hook allows you to use state in functional components.
  • useEffect: This Hook allows you to perform side effects in functional components.

useState

The useState Hook allows you to use state in functional components. It takes a single argument, which is the initial state, and returns an array with two elements: the current state and a function that allows you to update the state.

To use the useState Hook, you need to import it from the react package and call it inside your functional component. The Hook will return an array with two elements: the current state and a function that allows you to update the state.

Here is an example of how to use the useState Hook to add state to a functional component:

import React, { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

In this example, the useState Hook is called with an initial state of 0. The Hook returns an array with the current state (count) and a function that allows you to update the state (setCount).

The count variable is used to display the current state, and the setCount function is used to update the state when the button is clicked.

useEffect

The useEffect Hook allows you to perform side effects in functional components. It takes a function as an argument, which is called the effect, and an optional array of dependencies.

The effect function is called after the component is rendered, and it allows you to perform side effects, such as making API requests, setting up subscriptions, and updating the DOM. The optional array of dependencies is used to specify which values the effect depends on. If the array is not provided, the effect will run every time the component is rendered. If the array is provided, the effect will run only when one of the values in the array changes.

Here is an example of how to use the useEffect Hook to make an API request in a functional component:

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

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return (
    <div>
      {data ? <p>{data.message}</p> : <p>Loading...</p>}
    </div>
  );
}

In this example, the useEffect Hook is called with an effect function that makes an API request to https://api.example.com/data and updates the data state with the response. The effect function is called after the component is rendered, and it will run only once because the optional array of dependencies is empty.

Conclusion

React Hooks are a new feature in React 16.8 that allow you to use state and other React features in functional components. They are a way to reuse stateful logic, not state itself, and they provide an easy way to use React concepts in functional components.

Hooks are a powerful tool that can help you build efficient and scalable React applications. By creating reusable logic with Hooks, you can simplify your code and make it easier to understand and maintain.

There are many other Hooks available in React, such as the useContext Hook, which allows you to use context in functional components, and the useReducer Hook, which allows you to use a reducer in functional components.

In addition to the built-in Hooks, you can also create your own custom Hooks to reuse logic between components. Custom Hooks are a way to extract reusable logic from a component and make it available to other components.

To learn more about React Hooks and how to use them, you can refer to the official React documentation and explore the various examples and tutorials available online.

Exercises

To review these concepts, we will go through a series of exercises designed to test your understanding and apply what you have learned.


Create a functional component called MyForm that includes a form with a single input field and a submit button. Use the useState Hook to add state to the component and store the value of the input field.

import React, { useState } from 'react';

function MyForm() {
  const [inputValue, setInputValue] = useState('');

  const handleSubmit = event => {
    event.preventDefault();
    console.log(inputValue);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={inputValue} onChange={event => setInputValue(event.target.value)} />
      <button type="submit">Submit</button>
    </form>
  );
}


Add a useEffect Hook to the MyForm component that logs the value of the input field to the console when the form is submitted.

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

function MyForm() {
  const [inputValue, setInputValue] = useState('');

  useEffect(() => {
    console.log(inputValue);
  }, [inputValue]);

  const handleSubmit = event => {
    event.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={inputValue} onChange={event => setInputValue(event.target.value)} />
      <button type="submit">Submit</button>
    </form>
  );
}


Create a custom Hook called useDebounce that delays the execution of a function for a specified amount of time. Use the useDebounce Hook in the MyForm component to debounce the form submission for 500 milliseconds.

import { useState, useEffect } from 'react';

function useDebounce(fn, delay) {
  const [debouncing, setDebouncing] = useState(false);

  useEffect(() => {
    if (debouncing) {
      const timeoutId = setTimeout(() => {
        setDebouncing(false);
        fn();
      }, delay);

      return () => clearTimeout(timeoutId);
    }
  }, [debouncing, fn, delay]);

  return debouncing;
}

function MyForm() {
  const [inputValue, setInputValue] = useState('');
  const debouncing = useDebounce(() => console.log(inputValue), 500);

  const handleSubmit = event => {
    event.preventDefault();
    setDebouncing(true);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={inputValue} onChange={event => setInputValue(event.target.value)} />
      <button type="submit" disabled={debouncing}>
        Submit
      </button>
    </form>
  );
}


Create a functional component called MyList that displays a list of items. Use the useState Hook to add state to the component and store the list of items.

import React, { useState } from 'react';

function MyList() {
  const [items, setItems] = useState([]);

  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}


Add a useEffect Hook to the MyList component that fetches a list of items from an API and updates the state when the component is rendered.

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

function MyList() {
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetch('https://api.example.com/items')
      .then(response => response.json())
      .then(data => setItems(data));
  }, []);

  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}