🌍 ReactJS · flashcards
ReactJS React Hooks Flashcards
49 question-and-answer cards covering React Hooks as it is examined in ReactJS. 24 of them are printed below, taken from across the deck — no signup, no paywall on the preview.
24 sample cards from the React Hooks deck
Sampled from the end of the deck, so these are different cards from the ones shown on the syllabus page.
What does the `useMemo` Hook do and what does it return?
`useMemo(calculateValue, deps)` returns a memoized value. It runs `calculateValue` during render and caches its result, recomputing only when a dependency changes; otherwise it returns the cached value from the previous render.
Give two legitimate use cases for `useMemo`.
1) Caching an expensive calculation so it isn't repeated on every render. 2) Preserving referential identity of an object/array/derived value so that `React.memo` children or Hook dependency arrays don't see a new reference each render.
How do `useMemo` and `useCallback` differ in what they memoize?
`useMemo` memoizes the return value of calling a function (`useMemo(() => compute(), deps)`), while `useCallback` memoizes the function reference itself (`useCallback(fn, deps)`). Use `useMemo` for computed values, `useCallback` for functions.
Is it safe to skip `useMemo`/`useCallback`, and what is the tradeoff?
Yes—they are performance optimizations, not correctness requirements; React will still work without them. The tradeoff is that they add memory and comparison overhead, so they should be used only when profiling shows a real benefit (expensive compute or preventing child re-renders).
What is a custom Hook in React?
A custom Hook is a JavaScript function whose name starts with `use` and that calls one or more built-in Hooks. It lets you extract and reuse stateful logic across components without changing the component hierarchy.
What naming convention must a custom Hook follow and why?
Its name must start with `use` (e.g. `useFetch`, `useToggle`). This convention lets React and linters recognize it as a Hook so they can enforce the Rules of Hooks (only call Hooks at the top level, only from React functions/Hooks).
Do two components using the same custom Hook share state?
No. Each call to a custom Hook creates completely independent state. Custom Hooks share stateful logic, not the state itself—every component (and every separate call) gets its own isolated instance of the Hook's state and effects.
State the two Rules of Hooks.
1) Only call Hooks at the top level—never inside loops, conditions, nested functions, or after an early return. 2) Only call Hooks from React function components or from other custom Hooks—not from regular JavaScript functions or class components.
Why must Hooks be called in the same order on every render?
React tracks Hook state by call order (an index into an internal list), not by name. Calling Hooks conditionally or in a different order shifts the indices, so React associates state with the wrong Hook, corrupting state. Consistent top-level ordering keeps the mapping stable.
What should a custom Hook return, and is it required to return anything?
It can return anything useful—a single value, an array (like `useState`), or an object. It is not required to return anything; some custom Hooks only run effects (e.g. `useDocumentTitle`). The return shape is a design choice for the caller's ergonomics.
When reusing logic, what is the difference between sharing a custom Hook and sharing a plain utility function?
A plain utility function contains no React state or effects and cannot call Hooks. A custom Hook can call built-in Hooks, so it can encapsulate stateful, effectful React logic (state, subscriptions, lifecycle) that plain functions cannot.
Should you extract every piece of logic into a custom Hook? What is the guideline?
No. Extract a custom Hook when the logic is reused across components, or when it clarifies a complex effect/state pattern by giving it a descriptive name. Avoid over-abstracting trivial or single-use logic, which can add indirection without benefit.
Sketch a custom `useToggle` Hook and explain what it returns.
```js function useToggle(initial = false) { const [on, setOn] = useState(initial); const toggle = useCallback(() => setOn(o => !o), []); return [on, toggle]; }``` It returns the boolean state and a stable `toggle` function that flips it, encapsulating boolean-toggle logic for reuse.
Sketch a custom `usePrevious` Hook that returns the previous value of a prop or state.
```js function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; }``` The ref is updated after render, so during a render `ref.current` still holds the value from the previous render.
Sketch a custom `useLocalStorage` Hook (state synced to localStorage).
```js function useLocalStorage(key, initial) { const [value, setValue] = useState( () => JSON.parse(localStorage.getItem(key)) ?? initial ); useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; }``` It reads the initial value lazily and writes to localStorage whenever the value or key changes.
Sketch a custom `useFetch` Hook that loads data from a URL and reports loading/error state.
```js function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let active = true; setLoading(true); fetch(url).then(r => r.json()) .then(d => active && (setData(d), setLoading(false))) .catch(e => active && (setError(e), setLoading(false))); return () => { active = false; }; }, [url]); return { data, loading, error }; }``` The cleanup flag prevents setting state after unmount or on a stale request.
Why does a `useFetch`-style effect commonly use an `active`/`ignore` flag or `AbortController` in its cleanup?
To avoid race conditions and "can't update unmounted component" issues: if the URL changes or the component unmounts before the request resolves, the cleanup marks the response as stale (or aborts it), so an out-of-date response doesn't overwrite fresh state.
Sketch a custom `useDebounce` Hook that returns a debounced value.
```js function useDebounce(value, delay) { const [debounced, setDebounced] = useState(value); useEffect(() => { const id = setTimeout(() => setDebounced(value), delay); return () => clearTimeout(id); }, [value, delay]); return debounced; }``` Each new value restarts the timer via cleanup, so `debounced` only updates after `delay` ms of no changes.
Sketch a custom `useWindowSize` Hook using an event subscription.
```js function useWindowSize() { const [size, setSize] = useState({ w: window.innerWidth, h: window.innerHeight }); useEffect(() => { const onResize = () => setSize({ w: window.innerWidth, h: window.innerHeight }); window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, []); return size; }``` It subscribes on mount and unsubscribes in cleanup to prevent leaks.
Can a custom Hook call other custom Hooks, and what is a common example?
Yes—custom Hooks can compose other Hooks (built-in or custom). For example, `useFetch` might call `useState` and `useEffect`, and a higher-level `useUser(id)` might call `useFetch(`/users/${id}`)`, building layered, reusable abstractions.
How do you pass information from a component into a custom Hook, and how does the Hook stay up to date?
You pass information as arguments (props/state), e.g. `useFetch(url)`. Because the component re-renders when its state/props change, it calls the Hook again with fresh arguments, so the Hook always receives the latest values on each render.
What problem with class components did custom Hooks solve compared to HOCs and render props?
Reusing stateful logic previously required Higher-Order Components or render props, which caused "wrapper hell" (deeply nested component trees) and made data flow hard to follow. Custom Hooks reuse logic without adding wrapper components, keeping the tree flat and the logic colocated.
Why can't you call a Hook conditionally like `if (cond) { useState(...) }`?
Because it breaks Rule 1 (call Hooks at the top level). Conditional calls change how many Hooks run and in what order between renders, so React's index-based state tracking mismatches. Instead, put the condition inside the Hook, or always call the Hook and branch on its result.
In `const [state, dispatch] = useReducer(...)`, is the `dispatch` function stable across re-renders?
Yes. React guarantees that the `dispatch` function identity is stable for the lifetime of the component, so it is safe to omit from `useEffect`/`useCallback` dependency arrays and to pass down without causing extra re-renders.
What this deck covers
The React Hooks deck follows the ReactJS React Hooks syllabus — 3 chapters and 9 topics — so questions land on material that is genuinely examinable rather than trivia around it. That works out to roughly 16.3 cards per chapter.
Answers are written to be recallable, not just readable — averaging about 280 characters, which is long enough to carry the reasoning and short enough to say out loud.
A deck like this earns its keep on the second and third pass. Read the syllabus first so you know the shape of the subject, then use the cards to find the specific facts that have not stuck.
React Hooks flashcards FAQ
How many React Hooks flashcards are in this ReactJS deck?
49 cards. This page previews 24 of them, sampled evenly across the deck so you can judge the difficulty before installing anything.
Are these ReactJS flashcards free?
Yes. The preview here is free to read with no signup, and the full 49-card deck is free inside the Examius app.
What do the React Hooks cards cover?
They follow the ReactJS React Hooks syllabus — 3 chapters and 9 topics — so the questions track what is actually examinable.
How should I use these flashcards?
Read the syllabus first so you know the shape of the subject, then drill the deck. Examius schedules each card with spaced repetition, so cards you keep missing come back sooner and ones you know drift further apart.