🌍 ReactJS · subject

ReactJS React Hooks Syllabus

The React Hooks syllabus for ReactJS in full: 3 chapters and 9 topics, every one listed below, plus 49 React Hooks flashcards with answers.

3Chapters
9Topics
49Flashcards

React Hooks syllabus: all 3 chapters

Expand any chapter to see its topics and sub-topics.

  1. Basic Hooks

    3 topics
    • useState
    • useEffect
    • useContext
  2. Additional Hooks

    3 topics
    • useReducer
    • useCallback
    • useMemo
  3. Custom Hooks

    3 topics
    • Creating Custom Hooks
    • Reusing Logic with Custom Hooks
    • Examples of Custom Hooks

ReactJS React Hooks flashcards — 49 questions with answers

  1. What is the `useState` Hook and what does it return?

    `useState` is a React Hook that lets a function component hold local state. It returns an array of exactly two elements: the current state value and a setter function to update it, e.g. `const [count, setCount] = useState(0)`. Its argument is the initial state.

  2. How does the state updater from `useState` behave when you pass it a function, e.g. `setCount(c => c + 1)`?

    Passing a function (the functional/updater form) gives that function the latest pending state as its argument and uses its return value as the next state. It is the safe way to update state based on the previous value, especially when multiple updates are batched in one render.

  3. What is a lazy initializer in `useState` and when should you use it?

    If you pass a function as the argument, `useState(() => expensiveInit())`, React calls it only once on the initial render to compute the starting state. Use it when the initial value is expensive to compute so the work isn't repeated on every render.

  4. Does calling a `useState` setter immediately change the state variable within the same render?

    No. State updates are asynchronous with respect to the current render; the variable keeps its value until the next render. React schedules a re-render, and the new value is only visible in the following render's execution.

  5. What happens if you call a `useState` setter with a value equal (by `Object.is`) to the current state?

    React bails out and skips re-rendering that component (and its children), because `Object.is` comparison shows the state has not changed. This is an optimization to avoid unnecessary renders.

  6. Why must state updates to objects and arrays with `useState` be immutable?

    React compares the new state reference to the old one with `Object.is`. Mutating the existing object/array keeps the same reference, so React won't detect a change or re-render. You must create a new object/array (e.g. spread) so the reference differs.

  7. What is the purpose of the `useEffect` Hook?

    `useEffect` lets you run side effects (data fetching, subscriptions, manual DOM changes, timers) after render. It synchronizes a component with an external system, running after the DOM has been committed/painted.

  8. How does the dependency array of `useEffect` control when the effect runs? Compare `[]`, no array, and `[a, b]`.

    No array: the effect runs after every render. `[]` (empty): runs only once after the initial mount. `[a, b]`: runs after the first render and again whenever any listed dependency changes (compared with `Object.is`).

  9. What is the cleanup function in `useEffect` and when does it run?

    The function you return from the effect. React runs it before the effect re-runs (to clean up the previous effect) and when the component unmounts. It is used to unsubscribe, clear timers, or close connections to prevent leaks.

  10. In what order do the cleanup and setup of a dependency-changed `useEffect` run across re-renders?

    On each re-render where a dependency changed, React first runs the previous effect's cleanup, then runs the new effect's setup. So the sequence is: cleanup(old) → setup(new).

  11. When (relative to the browser paint) does `useEffect` fire, and how does that differ from `useLayoutEffect`?

    `useEffect` fires asynchronously after the browser has painted the screen. `useLayoutEffect` fires synchronously after DOM mutations but before the browser paints, so use it for DOM measurements/layout to avoid visual flicker.

  12. What causes an infinite loop with `useEffect`, and how is it avoided?

    Updating state inside an effect that also lists that state (or an unstable object/function) as a dependency causes re-render → effect → state update → re-render endlessly. Avoid it by fixing the dependency array, using functional updates, or memoizing objects/functions.

  13. Why does React (in development, Strict Mode) mount, unmount, and remount components, and how does that affect effects?

    In development Strict Mode, React deliberately runs each effect an extra time (setup → cleanup → setup) to surface missing or incorrect cleanup. It has no effect in production; it forces you to write effects that are resilient to re-running.

  14. What is the `useContext` Hook and what does it read?

    `useContext(SomeContext)` reads and subscribes to the current value of a React context. It returns the value of the nearest matching `<SomeContext.Provider>` above the component in the tree, letting you avoid prop drilling.

  15. When a context value changes, which components re-render?

    Every component that calls `useContext` for that context re-renders when the provider's `value` changes (compared with `Object.is`), regardless of `memo`. Components that don't consume the context are not forced to re-render by the context change itself.

  16. What value does `useContext` return when there is no matching Provider above the component?

    It returns the default value that was passed to `createContext(defaultValue)`. If no default was specified, it returns whatever default was given (often `undefined` or `null`).

  17. Why should the `value` prop of a context Provider often be memoized?

    If `value` is an inline object/array/function, it gets a new reference on every render of the Provider's parent, forcing all consumers to re-render. Wrapping it in `useMemo`/`useCallback` keeps the reference stable so consumers only re-render when the data truly changes.

  18. What is the `useReducer` Hook and what does it return?

    `useReducer` manages state via a reducer function. Called as `const [state, dispatch] = useReducer(reducer, initialArg, init?)`, it returns the current state and a `dispatch` function. You update state by calling `dispatch(action)`.

  19. What is the signature of a reducer function used with `useReducer`?

    `(state, action) => newState`. It is a pure function that takes the current state and an action object, and returns the next state. It must not mutate the existing state or perform side effects.

  20. When should you prefer `useReducer` over `useState`?

    Prefer `useReducer` when state logic is complex, involves multiple sub-values, the next state depends heavily on the previous state, or when many event handlers update state in related ways. It centralizes transitions and makes updates easier to test and debug.

Show the other 29 React Hooks flashcards
  1. What is the optional third argument (`init`) of `useReducer` used for?

    It is a lazy initializer function. React computes the initial state as `init(initialArg)`, letting you extract initialization logic and reset state (e.g. by calling `dispatch` with an action that recomputes `init`). It also avoids recomputing on every render.

  2. Compare `useReducer` and Redux at a conceptual level.

    Both use `(state, action) => newState` reducers and `dispatch`. `useReducer` is local component state with no store, middleware, or global provider by default; Redux is a global, single-store solution with middleware, devtools, and cross-component sharing. `useReducer` + `useContext` can emulate a lightweight global store.

  3. What does the `useCallback` Hook do and what does it return?

    `useCallback(fn, deps)` returns a memoized version of the callback `fn`. It returns the same function reference between renders as long as the dependencies are unchanged, recreating it only when a dependency changes.

  4. State the relationship: `useCallback(fn, deps)` is equivalent to what expression using `useMemo`?

    `useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`. `useCallback` memoizes the function itself, whereas `useMemo` would memoize the result of calling a function.

  5. When is `useCallback` actually useful (i.e., when does it prevent unnecessary work)?

    When the memoized function is passed to a `React.memo`-wrapped child (so a stable reference prevents the child re-rendering), or when it is a dependency of another Hook like `useEffect`/`useMemo`. Without such consumers, it usually adds overhead without benefit.

  6. 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.

  7. 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.

  8. 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.

  9. 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).

  10. 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.

  11. 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).

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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.

  17. 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.

  18. 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.

  19. 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.

  20. 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.

  21. 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.

  22. 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.

  23. 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.

  24. 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.

  25. 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.

  26. 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.

  27. 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.

  28. 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.

  29. 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.

ReactJS React Hooks FAQ

What is in the ReactJS React Hooks syllabus?

ReactJS React Hooks is split into 3 chapters: Basic Hooks, Additional Hooks and Custom Hooks. Together they contain 9 topics.

How many chapters are in ReactJS React Hooks?

3 chapters, containing 9 topics. The largest chapter is Basic Hooks, with 3 topics.

Are there flashcards for ReactJS React Hooks?

Yes — a 49-card React Hooks deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.