Logo
Published on

Most Popular React Hooks Explained with Examples

Authors
  • Name
    Twitter

I wanted to explain the most popular React hooks in short sentences and with examples. Both to help you guys with understanding React, but also to refresh my knowledge.

1. useState

Creates an “state variable” which updates the component on change.

useState is the most common hook in React. The hook needs 3 inputs to create a state.

  1. Current state (count): The name of the variable, which is equal to the current state.
  2. Function (setCount): A function which gets called to change the state.
  3. Initial value (0): The default value when page initialised.
import { useState } from "react";  
  
const App = () => {  
  const [count, setCount] = useState(0);  
  
  return (  
    <div>  
      <h1>{count}</h1>  
      <button onClick={() => setCount(count + 1)}>Add 1 to count</button>  
    </div>  
  );  
};

2. useEffect

A function which gets called every time the view gets mounted, or when the state inside [] changes.

useEffect is very often used in React. One of the key things to notice when using useEffect, is the second param: []. Their is a big difference between leaving the squared brackets empty, or entering a state(s).

  • Empty []: This means that the useEffect() only gets called once upon mounting.
  • Filled [count]: This means that the useEffect() gets called on mounting, and when the state (count) changes.
import { useEffect, useState } from "react";  
  
const App = () => {  
  const [count, setCount] = useState(0);  
  
  useEffect(() => {  
    console.log("View Mounted");  
  }, []);  
  
  useEffect(() => {  
    console.log("View Mounted or Count updated");  
  }, [count]);  
    
  // .. //  
};

3. useRef

A hook which can store a mutable value, which does not re-render the view on update.
Also, it can be used to store DOM elements.

The most common use of useRef, is to store an element, which then can be accessed within the component. This can be useful when creating a input field, where you e.g. need to access the value.

import { useRef } from "react";  
  
const App = () => {  
  const inputRef = useRef();  
  
  return (  
    <input  
      ref={inputRef}  
      onChange={() => {  
        console.log(inputRef.current.value);  
      }}  
    />  
  );  
};

4. useMemo

A function which only gets called every time an specific state changes.

useMemo works very similar to useEffect, since it only gets called every time the state within the squared brackets changes. This can be useful when calling an API, which shouldn’t be called every time the component refreshes.

import { useState, useMemo } from "react";  
  
const App = () => {  
  const [apiURL, setApiURL] = useState("https://callAPI/");  
  
  const apiResults = useMemo(() => {  
    callAPI();  
  }, [apiURL]);  
  
  return (  
    <div>  
      <button onClick={() => setApiURL("https://dummyAPI")}>Change API Url</button>  
    </div>  
  );  
};  
  
const callAPI = () => {  
  console.log("Call API");  
};

5. useCallback

Works exactly like useMemo, but instead of returning a value, it returns a function.

useCallback works exactly the same as useMemo. However instead of calling the function when the state changes, it sets up a function which then becomes callable.
This can be useful when needing to pass props into the function.

// Returns the value 100  
const apiResults = useMemo(() => {  
  return 100  
}, [apiURL]);  
  
// Returns a function, which then can be called  
const getApiResults = useCallback((value) => {  
  return 100 + value  
}, [apiURL]);

6. useContext

Creates a state which is accessible from all components.

In this example we are looking at how to share a state variable among two components, which declares if the application is dark themed.
Normally you would have to pass this information through props, but this would be very painfull when working with multiple components.

Therefore we can use useContext, which creates an state variable, which can be accessed from all components, without the need for props.

// App.jsx //  
  
import { useState, createContext } from "react";  
  
export const ThemeContext = createContext(null);  
  
const App = () => {  
  const [isDarkThemed, setIsDarkThemed] = useState(false);  
  
  return (  
    <ThemeContext.Provider value={isDarkThemed}>  
      <button onClick={() => setIsDarkThemed((prev) => !prev)}>  
        Change Theme  
      </button>  
      <AboutPage />  
    </ThemeContext.Provider>  
  );  
};  
  
export default App;

We can then fetch the isDarkThemed value in AboutPage.jsx

// AboutPage.jsx //  
  
import { useContext } from "react";  
import { ThemeContext } from "./App";  
  
const AboutPage = () => {  
  const isDarkTheme = useContext(ThemeContext);  
  
  return (  
    <div style={{ backgroundColor: isDarkTheme ? "black" : "white" }}>  
      // .. //  
    </div>  
  );  
};

7. useReducer

Works similar to useState, but instead of having a single value, it contains an object.

Difference between useState and useReducer:

  • useState can only store one value, e.g. “0”.
  • useReducer can store an object, which can have multiple values. Also, it contains the dispatch function, which simplifies more advanced functionality.

useReducer should be used when you have an object, which has multiple state values. E.g. when storing an user object, which has a name, email and _number.
_Then it is simpler to have 1 useReducer, compared to 3 useState’s for each user values.

function reducer(state, action) {  
  switch (action.type) {  
    case "increment":  
      return { count: state.count + 1 };  
  
    case "decrement":  
      return { count: state.count - 1 };  
  
    default:  
      return state;  
  }  
}  
  
const App = () => {  
  const [state, dispatch] = useReducer(reducer, { count: 0 });  
  
  return (  
    <div>  
      <h1>{state.count}</h1>  
      <button onClick={() => dispatch({ type: "increment" })}>Increase</button>  
      <button onClick={() => dispatch({ type: "decrement" })}>Decrease</button>  
    </div>  
  );  
};

8. useLayoutEffect

Works similar to useEffect, but instead gets called before view gets mounted.

Difference between useEffect and useLayoutEffect:

  • useEffect gets called when the view appears or mounted.
  • useLayoutEffect gets called before the view appears or mounted.

This can be useful when needing to show list of items instantly upon screen display, without it causing a small blink/flash.

Warning: React official docs say: “useLayoutEffect can hurt performance. Prefer useEffect when possible.”

import { useLayoutEffect} from "react";  
  
const App = () => {  
  useLayoutEffect(() => {  
    console.log("View has not mounted yet");  
  }, []);  
    
  // .. //  
};

That's it for this topic. Thank you for reading!