Hook Internals

Preview — 3 of 10 questions

What problem does useSyncExternalStore solve?

javascript
function useThirdPartyStore(selector) {
  return useSyncExternalStore(
    store.subscribe,     // subscribe(callback) — called when store changes
    () => selector(store.getState()),      // getSnapshot — client
    () => selector(serverStore.getState()) // getServerSnapshot — SSR
  );
}

const count = useThirdPartyStore(state => state.count);
AIt's just a wrapper around useState with no additional guarantees
BIt replaces useEffect for all subscription patterns
CIt subscribes to external (non-React) stores safely in concurrent mode — prevents "tearing" (different components reading different versions of the store in the same render pass)
DIt only works with Redux stores

How do you show a pending state during a transition?

javascript
function TabContainer() {
  const [tab, setTab] = useState("about");
  const [isPending, startTransition] = useTransition();

  const selectTab = (nextTab) => {
    startTransition(() => {
      setTab(nextTab);
    });
  };

  return (
    <>
      <TabButton onClick={() => selectTab("about")} isActive={tab === "about"}>About</TabButton>
      <TabButton onClick={() => selectTab("posts")} isActive={tab === "posts"}>Posts</TabButton>

      {isPending ? <Spinner /> : null}
      <TabPanel tab={tab} />
    </>
  );
}
AisPending is true while React processes the transition — the current UI stays visible and interactive; <Spinner /> shows during the deferred render; no jarring unmount
BisPending is always false — transitions never show loading state
CuseTransition blocks user interaction during the pending state
DisPending works only with Suspense boundaries

How do you test a custom hook?

javascript
import { renderHook, act } from "@testing-library/react";
import { useCounter } from "./useCounter";

test("should increment counter", () => {
  const { result } = renderHook(() => useCounter(0));

  expect(result.current.count).toBe(0);

  act(() => {
    result.current.increment();
  });

  expect(result.current.count).toBe(1);
});
AYou must render a full component to test hooks
Bact() is not needed when testing hooks
CrenderHook creates a minimal component wrapper to host the hook — result.current holds the hook's return value; act() flushes state updates before assertions
DrenderHook only works with useState hooks, not useEffect

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.