React Hooks
Wafa Bergaoui

Wafa Bergaoui @wafa_bergaoui

About: Software engineer

Location:
Tunisia
Joined:
May 22, 2020

React Hooks

Publish Date: Dec 8 '24
75 6

Introduction

React Hooks are one of the most important advancements in React, simplifying state management and enabling functional components to be just as powerful as class components. They address several challenges faced in previous versions of React and have become the standard for modern React development.


What Are React Hooks?

React Hooks are functions that let you use React features (like state and lifecycle methods) in functional components. They enable cleaner, simpler, and more readable code.


Why Were Hooks Introduced?

React Hooks solve several issues present with class components:

  • Complexity of Classes:
    Managing lifecycle and state with this in class components was often error-prone. Hooks simplify this.

  • Logic Reusability:
    Hooks make it easier to reuse logic across components without using HOCs or render props.

  • Improved Code Readability:
    Hooks streamline component code, making it shorter and easier to understand.

  • Incremental Adoption:
    Hooks can be used alongside class components, allowing gradual migration.


Principle React Hooks

React provides several hooks. Let’s explore each with examples and detailed explanations.


1. useState

Manages state in functional components.

Example:

import React, { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0); // Initialize state

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

export default Counter;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • useState initializes the state variable count to 0.

  • setCount updates the state.


2. useEffect

Handles side effects like fetching data or updating the DOM.

Example:

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

function Timer() {
    const [time, setTime] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => setTime(t => t + 1), 1000);
        return () => clearInterval(interval); // Cleanup on unmount
    }, []); // Run once on mount

    return <p>Elapsed Time: {time}s</p>;
}

export default Timer;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Runs the effect once when the component mounts due to an empty dependency array [].

  • Cleans up the interval on unmount.


3. useContext

Accesses context values.

Example:

import React, { useContext, createContext } from 'react';

const ThemeContext = createContext('light');

function ThemedButton() {
    const theme = useContext(ThemeContext);

    return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>I am {theme} themed</button>;
}

function App() {
    return (
        <ThemeContext.Provider value="dark">
            <ThemedButton />
        </ThemeContext.Provider>
    );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • useContext fetches the value from the nearest ThemeContext.Provider

4. useReducer

Manages complex state logic.

Example:

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count - 1 };
        default:
            throw new Error('Unknown action type');
    }
}

function Counter() {
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <div>
            <p>Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
        </div>
    );
}

export default Counter;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • useReducer manages complex state transitions with actions.

5. useRef

Persists values or references DOM nodes.

Example:

import React, { useRef } from 'react';

function FocusInput() {
    const inputRef = useRef();

    const focus = () => inputRef.current.focus();

    return (
        <div>
            <input ref={inputRef} placeholder="Click button to focus" />
            <button onClick={focus}>Focus Input</button>
        </div>
    );
}

export default FocusInput;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The ref persists across renders and provides a reference to the DOM element.

6. useMemo

Memoizes expensive computations.

Example:

import React, { useMemo } from 'react';

function Factorial({ number }) {
    const factorial = useMemo(() => {
        const calculateFactorial = n => (n <= 1 ? 1 : n * calculateFactorial(n - 1));
        return calculateFactorial(number);
    }, [number]);

    return <p>Factorial of {number}: {factorial}</p>;
}

export default Factorial;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • useMemo avoids recalculating the factorial unless number changes.

7. useCallback

Memoizes a function.

Example:

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

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

    const increment = useCallback(() => setCount(prev => prev + 1), []);

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

export default Counter;

Enter fullscreen mode Exit fullscreen mode

Explanation:
Prevents unnecessary re-creation of increment on re-renders.


8. useLayoutEffect

Runs synchronously after DOM mutations (before painting).

Example:

import React, { useState, useLayoutEffect, useRef } from 'react';

function Box() {
    const boxRef = useRef();
    const [color, setColor] = useState('blue');

    useLayoutEffect(() => {
        console.log('Box dimensions:', boxRef.current.getBoundingClientRect());
    }, [color]);

    return (
        <div>
            <div ref={boxRef} style={{ width: 100, height: 100, background: color }}></div>
            <button onClick={() => setColor(color === 'blue' ? 'red' : 'blue')}>Toggle Color</button>
        </div>
    );
}

export default Box;

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • useLayoutEffect ensures the DOM is measured before the browser paints.

Conclusion

React Hooks simplify component logic, promote code reusability, and enhance developer productivity. By understanding and effectively using hooks, you can write cleaner, more performant React applications.

Master these hooks, and you’ll unlock the full potential of React!

Comments 6 total

  • Adijat Motunrayo Adeneye
    Adijat Motunrayo AdeneyeDec 8, 2024

    short and precise

  • Jorge Enrique Kike
    Jorge Enrique KikeDec 9, 2024

    Thanks to the new compiler in the new version (19) of React we will not use useMemo and UseCallback anymore. In short, React 19 doesn't completely eliminate the need for memo , useMemo and useCallback , but it reduces their necessity

    • Wafa Bergaoui
      Wafa BergaouiDec 9, 2024

      Thanks for pointing that out! You're right—React 19's new compiler reduces the need for useMemo and useCallback in many cases by handling re-renders more efficiently. That said, these hooks still have their uses, like optimizing expensive computations or memoizing functions in performance-critical scenarios.

      • BEST NEW SONGS
        BEST NEW SONGSFeb 19, 2025

        This forum is like finding a treasure! I can access all the information I need for free matka 420

  • Dexter Hale
    Dexter HaleDec 9, 2024

    well explained!

  • RickiLloyd
    RickiLloydDec 14, 2024

    React Hooks revolutionize the way we build React applications by enabling state and lifecycle management in functional components. They simplify code, promote reusability, and eliminate the need for class components, making development more intuitive and efficient. 🚀🎯

Add comment