We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Login to see the application

Engineers who find a new job through JavaScript Works average a 15% increase in salary 🚀

You will be redirected back to this page right after signin

Blog hero image

Working with advanced React Hooks

Damilola Adedoyin Ezekiel 7 January, 2022 | 7 min read

Introduction

Hooks are a new addition in React that lets you use state and other React features without writing a class. Hooks are functions that let you “hook into” React state and lifecycle features from function components.

Before the release of Hooks in React, you can only manipulate or update state using the lifecycle methods present in class components but using hook allows you to utilize the power of React without writing classes. Hooks offer a powerful and expressive new way to reuse functionality between components.

This article will cover the concept of hooks from basic to advanced and at the end of this article, you will understand when and how to use the different types of React Hooks in your application.

Rules of Hooks

There are rules guiding the usage of hooks and to avoid your codes from throwing errors, these rules have to be followed.

  • Hooks must be called inside a function or component body.
  • Do not call hooks conditionally, inside loops, or nested functions.
  • When naming hooks, it should start with the prefix 'use'. This applies to both custom hooks and the ones provided by React.
  • When using hooks, the component has to be in uppercase.

Working with Hooks

React provides different ways of using Hooks in applications. This means we can use different hooks in our application, depending on what we are trying to achieve. React also gives us the power to create custom hooks which allows us to reuse stateful logic. Isn't that awesome!!!

Let's get started by taking a look at the different Hooks in React 🚀

  • useState hook

The useState hook is used to manage and update state in React applications. It gives us an array to work with and this array is made of two values: the state and the setter function and this setter function is what we use to update our state. The useState hook also takes in a value of what the default state is.

Example:

import React, { useState } from "react";

const App = () => {

  const [text, setText] = useState(false);

  return (
    <div>
      <h2>{text === true ? "Sign In" : "Sign Up"}</h2>
      <button onClick={()=>setText(!text)}>Change Text.</button>
    </div>
  );
};
export default App;

View it live on CodeSandbox.

In the example above, the button updates the content of the h2 element whenever we click on it and this is only possible because of the useState hook.

First, we initialize a new state variable named text and a setter function named setText and then assign both variables to useState.

We then return two elements, the h2 element holds the value of the state itself and we declare a conditional statement to check if the state which is text equals true. If yes we want to display either Sign In or Sign Up

The button element takes in an onClick property which value is the setter function that we use to update our state. Each time we click on this button, React will re-render the component thereby passing the correct value to the h2element.

  • useEffect hook

The useEffect hook allows you to perform side effects in a function. Side effects include: fetching data from an API, changing DOM elements, pushing contents into an array, etc.

useEffect performs the function of componentDidMount, componentDidUpdate, and componentWillUnmount combined.

By default, useEffect runs after every re-render in the component, and most times we only want useEffect to run only when it is mounted. To solve this problem, we have to include a dependency array in the useEffect and this comes very handily in cases where we want to get data from an API. We do not want to call the API every time the component re-renders, we only want to call it as soon as useEffect is mounted.

useEffect ( () => {
  //do something here
}, [])

Let's take a look at how useEffect works with an example:

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

const App = () => {
  const [products, setProducts] = useState({});

  const fetchData = async () => {
    const response = await fetch("https://fakestoreapi.com/products?limit=5");
    const data = await response.json();
    setProducts(data)
  };

  useEffect(() => {
    fetchData();
  }, []);
  return (
    <div className="App">
      {products.map(({image, title, price,id})=>(
        <div key={id} className="container">
        <img src={image} alt="store" />
        <p>{title}</p>
        <p>{price}</p>
        </div>
      ))}
     
    </div>
  );
};

export default App;

screencapture-0jyjd-csb-app-2021-12-09-10_21_55.png

View it live on CodeSandbox .

From the example above, we are fetching data from a fake API, we map through the result gotten from the API and finally, we return the result.

  • useReducer Hook

The useReducer hook is a hook that is used for state management. You might be wondering why the useReducer hook is performing the same function as the useState hook.

Both the useReducer hook and useState hook are used for state management but the usage of either of them is based on the size of your application. useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values. It also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.

The useReducer hook syntax is quite similar to useState, only it takes in two parameters which are the reducer function and the initial state. The value of the initial state could be anything depending on what we're trying to initialize. It could be a number, function, array, object, etc.

Let's take a look at a demo of how to implement the useReducer hook in our code by building a simple counter.

import React, { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return state + 1;
    case "decrement":
      return state - 1;
    default:
      return state;
  }
}

const App = () => {
  const [count, dispatch] = useReducer(reducer, 0);
  return (
    <div className="App">
      <h1>Count: {count} </h1>
      <button onClick={() => dispatch({type:"decrement"})}>-</button>
      <button onClick={() => dispatch({type:"increment"})}>+</button>
    </div>
  );
};
export default App;

First, we declare an array that holds the current state and dispatch function and then assign it to the useReducer hook. The useReducer hook takes in two values which are the reducer function and an initial state. In this case, the initial state is 0.

Next, we return JSX elements that return values from the function. The h1 element holds the value of count and then two buttons that increase and decrease the value of count. Each of the buttons will have an onClick property and we will pass the dispatch function to it. The dispatch function also holds a parameter that represents the type of action we want to carry out, in this case, we want to increment and decrement.

Finally, we declare our reducer function outside the main function. This reducer function takes in two parameters which are state and action. Now we want to use a switch statement to check the type of action that has been declared in the dispatch function. So, if the type of action is increment, we want to increase the state by 1, and if it is decrement, we want to decrease the state by 1, else nothing should happen.

  • useContext

The useContext hook allows us to work with React's Context API, which itself is a mechanism to allow us to share data within its component tree without passing through props. It basically removes prop-drilling!

The useContext hooks accepts a context object which is the value returned from React.createContext and returns the current context value, as given by the nearest context provider for the given context.

Let's take a look at how it works by building a random password generator 🚀

import React,{useContext, createContext, useState} from "react";

const RandomPasswordContext = createContext();
const SetRandomPasswordContext = createContext();

function RandomPassword() {
  const randomPassword = useContext(RandomPasswordContext);
  return <div>Password: {randomPassword}</div>;
}

function PasswordGenerator() {
  let text =""
  let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  const setRandomNumber = useContext(SetRandomPasswordContext);
  const generateRandomNumber = () => {
      for (let i = 1; i < 7; i++){
    setRandomNumber (text+=characters.charAt(Math.floor(Math.random() * characters.length)));
  }
};
  return <button onClick={generateRandomNumber}>Generate Random Password</button>;
}

const App = () => {
  const [randomNumber, setRandomNumber] = useState(0);

  return (
    <div>
      <RandomPasswordContext.Provider value={randomNumber}>
        <SetRandomPasswordContext.Provider value={setRandomNumber}>
          <RandomPassword />
          <PasswordGenerator />
        </SetRandomPasswordContext.Provider>
      </RandomPasswordContext.Provider>
    </div>
  );
}

export default App

  • useRef

The useRef hook returns a mutable ref object, where the .current property is initialised to the passed argument(initial value). This hook makes it possible to access DOM nodes within functional component. We can use it as follows:

import React, {useRef} from "react";

const refContainer = useRef(initialValue)

This hook is used to deal with references to element and component in react. We can set a reference by passing the ref props to an element.

Let's take a look at the most common example on how to use the useRef hook 🚀

import React, { useEffect, useRef } from "react"

const App = () => {
  const inputEl = useRef(null);
  useEffect(() => {
    inputEl.current.focus();
  }, []);
  return <input ref={inputEl} type="text" />;
}

export default App;

From the example above, we are accessing the input element and we want to focus on the input element as soon as the component is mounted.

  • useCallback

  This Hook allows us to pass an inline callback function, and an array of dependencies, and will return a memoized version of the callback function. It is useful for when we want to prevent a function from being created on every render.

import React, {useState} from "react";

const Counter = ({increment}) => {
  return <button onClick={increment}>increase</button>;
};
const App = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count : {count}</p>
      <Counter increment={()=>setCount(count + 1)} />
    </div>
  );
};

export default App;

In the example above, every time the App component refreshes, the setCount function will be rendered. We can use the useCallback hook in order to prevent this from happening.

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

const Counter = ({increment}) => {
  return <button onClick={increment}>increase</button>;
};
const App = () => {
  const [count, setCount] = useState(0);
  const increment = useCallback(()=>{
    setCount(c => c + 1)
  },[setCount])
  return (
    <div>
      <p>Count : {count}</p>
      <Counter increment={increment} />
    </div>
  );
};

export default App;

  The useCallback Hook is useful when passing callbacks to optimised child components. It works similarly to the useMemo Hook, but for callback functions.

 - #### useMemo

  Memoization is an optimisation technique where the result of a function call is cached, and is then returned when the same input occurs again. The useMemo Hook allows us to compute a value and memoize it. We can use it as follows:

  import { useMemo } from 'react'

  const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

  The useMemo Hook is useful for optimisation when we want to avoid re-executing expensive operations.

  • useLayoutEffect

  This Hook is identical to useEffect, but it only fires after all Document Object Model (DOM) mutations. We can use it as follows:

  import { useLayoutEffect } from 'react'

  useLayoutEffect(didUpdate)

  The useLayoutEffect Hook can be used to read information from the DOM.

  Use the useEffect Hook when possible, because useLayoutEffect will block visual updates and slow down your application.

  • useDebugValue

  This Hook can be used to display a label in React DevTools when creating custom Hooks. We can use it as follows:

  import { useDebugValue } from 'react'

  useDebugValue(value)

You can use this Hook in custom Hooks to display the current state of your Hooks, as it will make it easier to debug them.

To learn more about React hooks, you can check out the official documentation

Thanks for reading 🚀 🚀

Related Issues

open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 16
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 5
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 5
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 7
  • Intermediate
  • HTML

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through JavaScript Works average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email