Skip to main content

Command Palette

Search for a command to run...

Understanding React Hooks

Updated
•3 min read•View as Markdown
O
My name is Oseni Oluwabunmi. I’m a software engineer, entrepreneur, and lifelong learner passionate about building meaningful solutions and growing ideas into impact. I balance ambition with curiosity, constantly exploring new skills, creating, and challenging myself to leave a mark

React hooks are functions that let us use react state and lifecycle inside functional components. They were initially introduced in react16.8. They eliminate the need for class components.

Why Hooks?

  • They help us write cleaner reusable code

  • They are easier to maintain

  • They help to reduce re-renders

💡
When using hooks always remember to call them at the top of your code i.e. not nest them in another code block and always call them inside react functions and not plain JavaScript code.

Core React Hooks

  1. useState

  2. useEffect

  3. useContext

  4. useRef

  5. useMemo

  6. useCallback

  7. Custom Hooks

useState

This allows you to initialize and track the state of components

Basic syntax of useState below

import { useState } from "react"; // Import useState hook from React

export default function Example() {  
  const [count, setCount] = useState(0); // Initialize state with default value 0

  return (
    <div>
      <h2>Count: {count}</h2> {/* Displays current state */}
      <button onClick={() => setCount(count + 1)}>Increment</button> {/* Updates state */}
      <button onClick={() => setCount(count - 1)}>Decrement</button> {/* Updates state */}
    </div>
  );
}

useEffect

The useEffect hook allows you to perform side effects in a functional component, such as:

  • Fetching data from an API.

  • Subscribing to events.

  • Updating the document title.

import { useState, useEffect } from "react"; // Import useState and useEffect

export default function Example() {  
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Component mounted or count changed!"); // Runs on mount and update

    return () => {
      console.log("Cleanup before next effect or unmounting.");
    };
  }, [count]); // Runs only when count changes

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

useContext

The useContext hook allows sharing state without passing props manually.

import { useContext, createContext } from "react";

// Create a Context
const ThemeContext = createContext();

export default function ParentComponent() {
  return (
    <ThemeContext.Provider value="dark">
      <ChildComponent />
    </ThemeContext.Provider>
  );
}

function ChildComponent() {
  const theme = useContext(ThemeContext); // Access the context value
  return <p>Current Theme: {theme}</p>;
}

useRef

The useRef hook allows you to:

Access DOM elements directly. Keep values without triggering re-renders.

import { useRef } from "react";

export default function Example() {  
  const inputRef = useRef(null); // Create a reference

  const focusInput = () => {
    inputRef.current.focus(); // Directly access DOM element
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="Type here..." />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

useMemo

The useMemo hook memoizes expensive calculations, preventing unnecessary re-computation.

import { useState, useMemo } from "react";

export default function Example() {  
  const [count, setCount] = useState(0);
  const [input, setInput] = useState("");

  const expensiveCalculation = useMemo(() => {
    console.log("Expensive computation running...");
    return count * 2;
  }, [count]); // Only recalculates if count changes

  return (
    <div>
      <h2>Expensive Value: {expensiveCalculation}</h2>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <input value={input} onChange={(e) => setInput(e.target.value)} />
    </div>
  );
}

useCallback

The useCallback hook memoizes functions to prevent unnecessary re-creation.

import { useState, useCallback } from "react";

export default function Example() {  
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount((prev) => prev + 1);
  }, []); // Memoized function

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={increment}>Increment</button>
    </div>
  );
}