Skip to solution
easyFrontend

What are React Hooks? Name a few common ones.

1.1k views
01

Understand the problem

Question presented to candidate: "What are Hooks, why were they introduced, and which ones do you actually reach for?"

What a strong answer should cover:

  • Hooks are functions that let a function component use React features — state, effects, context, refs — that previously required a class.
  • Introduced in React 16.8 (2019). The motivation: sharing stateful logic was only possible via HOCs and render props, both of which added wrapper components.
  • The Rules of Hooks: call them unconditionally, at the top level, and only from a component or another hook.
  • The common ones, grouped: useState/useReducer (state), useEffect/useLayoutEffect (effects), useContext (context), useRef (persistent values and DOM), useMemo/useCallback (memoisation).
  • Modern additions worth naming: useTransition, useDeferredValue, useSyncExternalStore, useId, and the React 19 set — useActionState, useOptimistic, useEffectEvent.
  • Custom hooks are the payoff: any use-prefixed function composing other hooks.
  • They did not replace classes for everything — Error Boundaries still need one.

Clarifying questions expected:

  • "Do you want the full list, or the ones I use day to day?"

Code / implementation expected: Optional. A component using two or three hooks together is enough.

hooksfunctional componentsstateside effects
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Anyone preparing for a React interview — assumes components and props. Difficulty: Easy

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. The hook inventory in section 4 was read directly off the installed React 19.2.8

Solution ready — 2 min read

Classified // press E to declassify

04

Explore the playground snippets

Six common hooks working together in one small component
Run Playground
import {
  useState, useEffect, useRef, useMemo, useCallback, useId, useContext, createContext,
} from "react";

const ThemeContext = createContext("light");

// A custom hook: composes two built-ins, shares logic with no wrapper component.
function useDebounced(value, ms) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), ms);
    return () => clearTimeout(id); // cleanup cancels the pending timer
  }, [value, ms]);
  return debounced;
}

const FRUIT = ["apple", "apricot", "banana", "blackberry", "cherry", "cranberry", "date"];

function Search() {
  const [query, setQuery] = useState("");          // useState  — local state
  const theme = useContext(ThemeContext);          // useContext — shared value
  const inputId = useId();                         // useId      — stable SSR-safe id
  const renders = useRef(0);                       // useRef     — persists, no re-render
  renders.current++;

  const debounced = useDebounced(query, 300);      // the custom hook

  // useMemo — recompute only when the debounced query actually changes.
  const results = useMemo(
    () => FRUIT.filter((f) => f.startsWith(debounced.toLowerCase())),
    [debounced],
  );

  // useCallback — a stable identity, safe to pass to a memoised child.
  const clear = useCallback(() => setQuery(""), []);

  return (
    <div style={{ color: theme === "dark" ? "#eee" : "#111" }}>
      <label htmlFor={inputId}>Filter fruit: </label>
      <input id={inputId} value={query} onChange={(e) => setQuery(e.target.value)} />{" "}
      <button onClick={clear}>clear</button>

      <p style={{ fontSize: 13, color: "#666" }}>
        typed: <strong>{query || "(empty)"}</strong> · debounced:{" "}
        <strong>{debounced || "(empty)"}</strong> · renders: <strong>{renders.current}</strong>
      </p>

      <ul>{results.map((r) => <li key={r}>{r}</li>)}</ul>
      {results.length === 0 && <p style={{ color: "#a33" }}>No matches.</p>}
    </div>
  );
}

export default function App() {
  return (
    <div style={{ padding: 24, fontFamily: "system-ui", lineHeight: 1.6 }}>
      <ThemeContext.Provider value="light">
        <Search />
      </ThemeContext.Provider>
      <p style={{ color: "#666", fontSize: 13 }}>
        Type quickly: the debounced value lags 300ms behind, and the filter only
        recomputes when it settles. The render counter comes from a ref, so
        reading it never causes a render of its own.
      </p>
    </div>
  );
}
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 2 of 119 decoded in the React.js track. One more won't hurt.

Back to track