Skip to the content.

React Hooks Cheatsheet

# React Hooks Cheatsheet A quick-reference guide for essential and advanced React Hooks (v18+), covering state, side effects, context, performance optimizations, DOM references, state reducers, and custom hooks. ## Rules of Hooks 1. **Only Call Hooks at the Top Level**: Do not call Hooks inside loops, conditions, or nested functions. Ensure they are always called in the exact same order on every render. 2. **Only Call Hooks from React Functions**: Call Hooks only from React Functional Components or Custom Hooks, never from regular JavaScript functions. --- ## State Hook: `useState` `useState` allows functional components to store and manage local reactive state. ```javascript import { useState } from 'react'; function Counter() { // Declaration: const [state, setter] = useState(initialValue); const [count, setCount] = useState(0); // 1. Basic Update const increment = () => setCount(count + 1); // 2. Functional Update (Always preferred when state depends on the previous state) const decrement = () => setCount(prevCount => prevCount - 1); // 3. Lazy Initial State (Used for expensive computations - runs only on initial render) const [data, setData] = useState(() => { return loadExpensiveDataFromStorage(); }); } ``` ## Side Effect Hook: `useEffect` `useEffect` handles asynchronous operations or DOM operations (fetching, subscriptions, manual DOM changes). ```javascript import { useEffect, useState } from 'react'; function DataFetcher({ userId }) { const [data, setData] = useState(null); useEffect(() => { let isMounted = true; const controller = new AbortController(); // Effect logic (commonly API fetching) async function fetchData() { const res = await fetch(`https://api.com/users/${userId}`, { signal: controller.signal }); const json = await res.json(); if (isMounted) setData(json); } fetchData(); // Cleanup Function (Runs when component unmounts or dependencies change) return () => { isMounted = false; controller.abort(); // Abort active network request to prevent memory leaks }; }, [userId]); // Dependency Array: Effect re-runs ONLY when 'userId' changes // Dependency Scenarios: // useEffect(() => {}) // Runs on EVERY render // useEffect(() => {}, []) // Runs ONCE on initial mount (equivalent to componentDidMount) // useEffect(() => {}, [x]) // Runs ONCE on mount, and whenever 'x' changes } ``` ## Context Hook: `useContext` `useContext` consumes values from a React Context directly, avoiding the need for deep prop-drilling. ```javascript import { createContext, useContext, useState } from 'react'; // 1. Create Context const ThemeContext = createContext(null); // 2. Provider Component export function ThemeProvider({ children }) { const [theme, setTheme] = useState('dark'); return ( {children} ); } // 3. Consume Context (Inside child components) function ThemeButton() { const { theme, setTheme } = useContext(ThemeContext); return ( ); } ``` ## Reference Hook: `useRef` `useRef` stores mutable values that do not trigger component re-renders when updated, or acts as a direct reference to access physical DOM nodes. ```javascript import { useRef, useEffect } from 'react'; function FocusInput() { // Scenario A: Accessing DOM elements const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); // Focus input element physically on mount }, []); // Scenario B: Storing mutable values (e.g. interval timers) without triggering re-renders const timerRef = useRef(null); const startTimer = () => { timerRef.current = setInterval(() => console.log("Tick"), 1000); }; const stopTimer = () => { clearInterval(timerRef.current); // Timer updated without causing a re-render }; } ``` ## Memoization Hooks: `useMemo` & `useCallback` These hooks cache (memoize) calculations or function references to avoid expensive re-computations or unnecessary re-renders of child components. ```javascript import { useMemo, useCallback, useState } from 'react'; function Search({ items }) { const [query, setQuery] = useState(''); // 1. useMemo: Caches the computed VALUE of an expensive function const filteredItems = useMemo(() => { console.log("Expensive filter running..."); return items.filter(item => item.name.toLowerCase().includes(query.toLowerCase())); }, [items, query]); // Only re-calculates when 'items' or 'query' changes // 2. useCallback: Caches the FUNCTION REFERENCE itself // Prevents child elements from triggering re-renders due to re-created function references on parent re-renders const handleSelect = useCallback((itemId) => { console.log("Selected item:", itemId); }, []); // Empty dependencies: reference remains identical across all re-renders } ``` ## State Reducer Hook: `useReducer` `useReducer` is an alternative to `useState` preferred for complex state objects, nested state transitions, or when the next state depends heavily on the previous one. ```javascript import { useReducer } from 'react'; const initialState = { count: 0, loading: false }; // Reducer Function: purely functional state transitions function reducer(state, action) { switch (action.type) { case 'increment': return { ...state, count: state.count + 1 }; case 'decrement': return { ...state, count: state.count - 1 }; case 'setLoading': return { ...state, loading: action.payload }; default: throw new Error(`Unhandled action type: ${action.type}`); } } // Consumer Component function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return (

Count: {state.count}

); } ``` ## Custom Hooks Custom Hooks are custom JavaScript functions whose names start with `use`. They let you extract and reuse stateful logic between components. ```javascript import { useState, useEffect } from 'react'; // Custom Hook to track browser window dimensions export function useWindowSize() { const [size, setWindowSize] = useState({ width: typeof window !== 'undefined' ? window.innerWidth : 1200, height: typeof window !== 'undefined' ? window.innerHeight : 800, }); useEffect(() => { const handleResize = () => { setWindowSize({ width: window.innerWidth, height: window.innerHeight }); }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); // Cleanup }, []); return size; } // Consumer component function ResponsiveComponent() { const { width } = useWindowSize(); // Consuming stateful window size logic instantly return

Window Width is {width}px

; } ```