DEV Community

Thomas Cook
Thomas Cook

Posted on

Introduction to React hooks

React Hooks

One of the many tools React has available to you is the use of hooks. Previously you had to write a class to utilize state and other React features. These hooks allow us to hook into parts of the React library. There are ten different types of hooks available, I will cover the first 5 here.

  • useState
  • useEffect
  • useContext
  • useRef
  • useReducer
  • useMemo
  • useCallback
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

The two most common are useState and useEffect.

useState
The most important and most used hook is useState. Its main purpose is to handle reactive data; basically anything that changes in the app uses state. Switching something from on to off or typing in an input field are examples of how useState is commonly implemented. Once any of the data changes, react can re-render the UI. useState requires three things:

useState needs to be imported into the component.

import { useState } from “react”;
Enter fullscreen mode Exit fullscreen mode

useState needs to be initialized. We do this by calling usesState in our function component.

const [food, setFood] = useState(“”);  // initializing with an empty string
Enter fullscreen mode Exit fullscreen mode

It needs a current state and a setter function to update that state. These last two requirements can be written in one line.

import { useState } from “react”;

function FavoriteFood() {
    const [food, setFood] = useState(“”); 
}
Enter fullscreen mode Exit fullscreen mode

The first value, food, is our current state. The second, setFood, is the function that updates our state. And useState is initialized to an empty string.

Always use the setter function to update your state.

setFood( “Cheeseburger”);
Enter fullscreen mode Exit fullscreen mode

useEffect
This hook allows you to perform side effects in your components. Such as timers and fetching data. useEffect accepts two arguments. The first argument is a function that will run when useEffect is triggered and the second is a dependency array that will hold which items will trigger the function, it is not required and by default will run on every render cycle. Like all hooks, useEffect needs to be imported as well.

import { useEffect } from “react’;
Enter fullscreen mode Exit fullscreen mode

useEffect runs on every render. And every re-render triggers another effect. Sometimes this is the desired outcome. If not there are a few ways to control when side effects run.

  • No dependency passed
  • An empty array
  • Props or state values
useEffect(() => {
    //No dependency passed
    //Runs on every render
});

useEffect(() => {
    //An empty array
    //runs only on the first render
}, []);

useEffect(() => {
    //Props or state values
    //Runs on the first render
    //And any time and dependency value changes
}, [prop, state]);
Enter fullscreen mode Exit fullscreen mode

Some effects require cleanup to reduce memory leaks. Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed of. We do this by including a return function at the end of the useEffect Hook.

return () => clearTimeout(timer)
}, []);
Enter fullscreen mode Exit fullscreen mode

useContext
This hook allows access to work with React’s Context API. This allows us to share data within its component tree without the need to be passed down to a component through props. It is a way to manage the state globally. useContext can be used in conjunction with useState to share state between deeply nested components. This is far easier than useState alone because the state should be held by the highest parent component that requires access to that state.
To use this hook you will need to import from react and initialize it.

import { useState, createContext, useContext } from “react”;

const UserContext = createContext()

Function Componet1() {
    Const [user, setUser] = useState(“Thomas Cook”);
    Return (
        <UserContext.Provider value={user}>
            <h1>{‘Hello ${user}!’}</h1>
            <Component2 user={user} />
        </UserContext.Provider>
    );
}
Function Component2() {
    Return (
        <>
            <h1>Component 2</h1>
            <Component3 />
        </>
    ):
}
Function Component3() {
    Const user = useContext(UserContext);

    Return (
        <>
            <h1>Component 3</h1>
            <h2>{‘Hello ${user} again!’}</h2>
        </>
    );
}
Enter fullscreen mode Exit fullscreen mode

The createContext function is used with the context provider to wrap the tree of components that need the state context. Then you can access the state context in all components

useRef
This hook allows you to persist values between renders. It can create mutable objects and is very similar to useState in that it tracks the changing values. The main difference is that useRef doesn’t trigger a re-render upon value changes. It only returns one item, an object called current. useRef is initialized and set with a value of useref(0).

Const count = {current: 0}
//can be accessed using .current
Count.current
Enter fullscreen mode Exit fullscreen mode

useReducer
useReducer is very similar to the useState hook. This hook also allows for custom state logic. useReducer may be useful in situations where you need to keep track of multiple pieces of state that rely on complex logic. It uses a Redux Pattern to manage state. Instead of updating state directly, we dispatch actions that go to a reducer function, and then figure out how to compute the next state.

Image description

Top comments (0)