React Hooks Cheatsheet!

Looking for a quick guide to mastering React Hooks? Unlock essential tips, tricks, and patterns!

react-hooks-cheatsheet

React Hooks Cheatsheet

React Hooks revolutionized how developers write React applications by bringing the features of class components, such as state and lifecycle methods, into functional components. Hooks enable cleaner, more efficient code and help you manage state, side effects, and reusable logic. This cheatsheet explains the most commonly used hooks with examples to help you get the most out of React.

1. useState - Manage State

The useState hook allows you to manage state in functional components. It lets you define state variables and provides a function to update them, triggering a re-render when the state changes.


import React, { useState } from 'react';

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

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

The useState hook takes an initial state value as an argument and returns an array with the current state and a function to update it. Whenever the state is updated, React re-renders the component.

2. useEffect - Handle Side Effects

The useEffect hook allows you to perform side effects in your components, such as fetching data, subscribing to external services, or updating the DOM. It runs after the component renders, and you can control when it runs by specifying dependencies.


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

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

    useEffect(() => {
        document.title = `Count: ${count}`;
    }, [count]);

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

useEffect runs after every render by default, but by passing a dependency array (in this case, [count]), you can control when it should run. If the dependency value hasn’t changed, React will skip the effect, which improves performance.

3. useContext - Access Context

The useContext hook provides a way to share values across your application without the need for prop drilling. It allows you to consume a context directly, avoiding the need to pass props down through every level of the component tree.


import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedButton() {
    const theme = useContext(ThemeContext);
    return <button style={{ backgroundColor: theme === 'light' ? '#fff' : '#333' }}>Click Me</button>;
}
    

useContext is useful when you need to pass down data to many components, such as user settings or themes, without passing it manually through props at every level.

4. useReducer - Manage Complex State Logic

The useReducer hook is an alternative to useState and is particularly useful when managing complex state logic that involves multiple values or actions. It works similarly to Redux by using a reducer function to update the state.


import React, { useReducer } from 'react';

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();
    }
}

function Counter() {
    const [state, dispatch] = useReducer(reducer, { count: 0 });

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

useReducer is especially helpful when the state depends on previous states or when state logic becomes complex. It provides a cleaner and more predictable way to manage updates compared to multiple useState calls.

5. useRef - Persistent Value and DOM Access

The useRef hook is used to persist values between renders or to reference DOM elements directly. Unlike useState, updates to a useRef value do not trigger a re-render.


import React, { useRef } from 'react';

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

    return (
        <div>
            <input ref={inputRef} />
            <button onClick={() => inputRef.current.focus()}>Focus Input</button>
        </div>
    );
}
    

useRef is commonly used for accessing DOM elements (like focusing an input field) or persisting a value across renders without causing re-renders.

6. useMemo - Optimize Expensive Computations

The useMemo hook memoizes the result of an expensive calculation, ensuring that the computation is only re-executed when its dependencies change. This can help optimize performance, especially for large data sets or complex calculations.


import React, { useMemo } from 'react';

function ExpensiveComputation({ numbers }) {
    const sum = useMemo(() => numbers.reduce((a, b) => a + b, 0), [numbers]);

    return <p>Sum: {sum}</p>;
}
    

useMemo helps you avoid unnecessary recalculations by caching the result of a function, only recalculating it when necessary (when the dependencies change).

7. useCallback - Memoize Functions

The useCallback hook memoizes a function, preventing it from being recreated on every render. This is useful when passing functions as props to child components, as it can prevent unnecessary re-renders of those components.


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

function ParentComponent() {
    const [count, setCount] = useState(0);
    const handleClick = useCallback(() => setCount((prev) => prev + 1), []);

    return (
        <div>
            <p>Count: {count}</p>
            <ChildComponent onClick={handleClick} />
        </div>
    );
}

function ChildComponent({ onClick }) {
    return <button onClick={onClick}>Increment</button>;
}
    

useCallback ensures that a function is only recreated if its dependencies change. This can improve performance when passing functions to child components.

8. useLayoutEffect - Synchronize Layout

The useLayoutEffect hook runs synchronously after the DOM has been updated but before the browser paints. It’s used for operations that require DOM layout measurements or adjustments before the user sees the updated UI.


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

function LayoutEffectExample() {
    const boxRef = useRef();

    useLayoutEffect(() => {
        console.log('Box width:', boxRef.current.offsetWidth);
    });

    return <div ref={boxRef}>I am a box.</div>
}
    

Use useLayoutEffect when you need to measure or manipulate the DOM before the browser paints the updates to the screen, such as adjusting the layout of a component.

9. Custom Hooks - Reusable Logic

Custom hooks allow you to extract reusable logic from components and share it across multiple components. This promotes modularity and helps keep components focused on rendering.


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

function useFetch(url) {
    const [data, setData] = useState(null);

    useEffect(() => {
        fetch(url)
            .then((response) => response.json())
            .then((data) => setData(data));
    }, [url]);

    return data;
}

function DataDisplay({ url }) {
    const data = useFetch(url);

    return <p>Data: {JSON.stringify(data)}</p>;
}
    

Custom hooks are great for abstracting away complex logic like data fetching, form validation, or state management, making your components easier to read and reuse.

Conclusion

React Hooks provide a powerful and flexible way to manage state, side effects, and reusable logic in functional components. By leveraging hooks like useState, useEffect, and useReducer, developers can build more modular, readable, and efficient React applications. Use this cheatsheet as a reference to get familiar with these essential hooks and optimize your React code.

Follow Us:

Stay updated with our latest tips and tutorials by subscribing to our YouTube Channel.


DevTools99

Developer Co-Team

Let us make it easier for developers throughout the world to breathe. Let's keep things simple. Let's take it easy.