Irbisa · Cheatsheet
Effects & Refs
useEffect and its dependencies, cleanup, race conditions, when you do not need an effect, useRef, useLayoutEffect, StrictMode double run
What is
useEffectfor, and when does it run?function ChatRoom({ roomId }: { roomId: string }) { useEffect(() => { const connection = createConnection(roomId); connection.connect(); return () => connection.disconnect(); // runs before the next effect and on unmount }, [roomId]); // reconnect only when roomId changes…How does the dependency array of
useEffectwork: no array, an empty array, and a list of values?useEffect(() => { document.title = `${count} new messages`;}); // after every render useEffect(() => { const id = setInterval(refreshClock, 1000);…What is the cleanup function of an effect, and when does React call it?
function useWindowWidth() { const [width, setWidth] = useState(window.innerWidth); useEffect(() => { const onResize = () => setWidth(window.innerWidth); window.addEventListener('resize', onResize);…What is
useRef, and how is it different from state?function Stopwatch() { const [elapsed, setElapsed] = useState(0); // shown on screen: state const intervalRef = useRef<number | null>(null); // not shown: ref function start() { if (intervalRef.current !== null) return;…How do you access a DOM element through a ref, and how do you pass a ref to your own component in React 19?
function TextInput({ ref, ...props }: React.ComponentProps<'input'>) { return <input ref={ref} className="input" {...props} />;} function SearchForm() { const inputRef = useRef<HTMLInputElement>(null);…Why do effects run twice in development, and how should you deal with it?
What is a race condition when fetching data in
useEffect, and how do you prevent it?type Hit = { id: string; title: string }; function SearchResults({ query }: { query: string }) { const [results, setResults] = useState<Hit[]>([]); useEffect(() => {…When do you not need an effect, and what do you use instead?
Find the bug: this effect runs in an endless loop and keeps sending requests.
function Products({ category }: { category: string }) { const [products, setProducts] = useState<Product[]>([]); const filters = { category, inStock: true }; useEffect(() => { fetchProducts(filters).then(setProducts); }, [filters]); return <ProductGrid items={products} />;}Find the bug: React logs "useEffect must not return anything besides a function", and the page goes blank when
userIdchanges.function Profile({ userId }) { const [user, setUser] = useState(null); useEffect(async () => { const response = await fetch(`/api/users/${userId}`); setUser(await response.json()); }, [userId]); return <h1>{user ? user.name : 'Loading...'}</h1>;}What does this component log on mount and after one click (without StrictMode)?
function Logger() { const [count, setCount] = useState(0); console.log('render', count); useEffect(() => { console.log('effect', count); return () => console.log('cleanup', count); }, [count]); return <button onClick={() => setCount(count + 1)}>{count}</button>;}How do you implement a
usePrevioushook, and what are its limits?// classic: the value from the previous renderfunction usePrevious<T>(value: T): T | undefined { const ref = useRef<T | undefined>(undefined); useEffect(() => { ref.current = value; });…Find the bug: the counter goes from 0 to 1 and then stops increasing.
function Ticker() { const [count, setCount] = useState(0); useEffect(() => { const id = setInterval(() => { setCount(count + 1); }, 1000); return () => clearInterval(id); }, []); return <p>{count}</p>;}What is the difference between
useEffectanduseLayoutEffect, and when do you need the latter?function Tooltip({ anchor, text }: { anchor: DOMRect; text: string }) { const ref = useRef<HTMLDivElement>(null); const [top, setTop] = useState(anchor.bottom); useLayoutEffect(() => { if (!ref.current) return;…What is
useImperativeHandle, and when would you expose methods through a ref?type VideoHandle = { play: () => void; pause: () => void }; function Video({ src, ref }: { src: string; ref?: React.Ref<VideoHandle> }) { const videoRef = useRef<HTMLVideoElement>(null); useImperativeHandle(ref, () => ({…How do you close a dropdown when the user clicks outside it?
function Dropdown({ items }: { items: string[] }) { const [open, setOpen] = useState(false); const rootRef = useRef<HTMLDivElement>(null); useEffect(() => { if (!open) return;…How do you use a library that owns its own DOM, such as a map or a chart, inside a React component?
import Chart from 'chart.js/auto'; function SalesChart({ labels, values }: { labels: string[]; values: number[] }) { const canvasRef = useRef<HTMLCanvasElement>(null); const chartRef = useRef<Chart<'line', number[], string> | null>(null);…How do you read the latest props or state inside an effect without re-running it, and what is
useEffectEvent?import { useEffect, useEffectEvent } from 'react'; function ChatRoom({ roomId, theme }: { roomId: string; theme: 'light' | 'dark' }) { const onConnected = useEffectEvent(() => { showNotification('Connected!', theme); // reads the latest theme });…What are callback refs, and what changed about them in React 19?
function MeasuredBox({ children }: { children: React.ReactNode }) { const [height, setHeight] = useState(0); const measure = useCallback((node: HTMLDivElement) => { const observer = new ResizeObserver(([entry]) => setHeight(entry.contentRect.height)); observer.observe(node);…