Episode 2 — React Frontend Architecture NextJS / 2.9 — Custom Hooks and Reusable Logic

2.9.b — Writing a useFetch hook: reusable API fetching

<< 2.9 Overview


Learning outcomes

  1. Implement useFetch(url) with loading / error / success states.
  2. Cancel in-flight fetches with AbortController.
  3. Know when to graduate to TanStack Query / SWR.

Shaped return API

Prefer a discriminated model over multiple booleans:

export type FetchState<T> =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "error"; message: string }
  | { status: "success"; data: T };

Implementation sketch

import { useEffect, useState } from "react";

export function useFetchJson<T>(url: string) {
  const [state, setState] = useState<FetchState<T>>({ status: "idle" });

  useEffect(() => {
    const ac = new AbortController();
    setState({ status: "loading" });

    (async () => {
      try {
        const res = await fetch(url, { signal: ac.signal });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = (await res.json()) as T;
        setState({ status: "success", data });
      } catch (e) {
        if ((e as Error).name === "AbortError") return;
        setState({ status: "error", message: (e as Error).message });
      }
    })();

    return () => ac.abort();
  }, [url]);

  return state;
}

Production note

Real apps usually want deduplication, caching, and background refetch—see 2.12. useFetch remains the pedagogical bridge.



Appendix — Scenario bank (basic → advanced)

Flashcard: symptom → cause → fix → interview phrase.

CH1-001 — useFetch #1

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 13 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-002 — useFetch #2

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 26 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-003 — useFetch #3

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 39 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-004 — useFetch #4

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 52 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-005 — useFetch #5

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 65 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-006 — useFetch #6

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 78 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-007 — useFetch #7

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 91 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-008 — useFetch #8

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 104 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-009 — useFetch #9

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 117 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-010 — useFetch #10

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 130 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-011 — useFetch #11

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 143 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-012 — useFetch #12

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 156 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-013 — useFetch #13

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 169 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-014 — useFetch #14

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 182 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-015 — useFetch #15

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 195 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-016 — useFetch #16

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 8 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-017 — useFetch #17

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 21 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-018 — useFetch #18

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 34 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-019 — useFetch #19

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 47 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-020 — useFetch #20

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 60 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-021 — useFetch #21

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 73 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-022 — useFetch #22

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 86 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-023 — useFetch #23

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 99 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-024 — useFetch #24

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 112 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-025 — useFetch #25

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 125 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-026 — useFetch #26

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 138 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-027 — useFetch #27

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 151 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-028 — useFetch #28

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 164 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-029 — useFetch #29

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 177 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-030 — useFetch #30

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 190 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-031 — useFetch #31

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 3 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-032 — useFetch #32

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 16 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-033 — useFetch #33

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 29 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-034 — useFetch #34

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 42 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-035 — useFetch #35

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 55 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-036 — useFetch #36

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 68 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-037 — useFetch #37

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 81 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-038 — useFetch #38

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 94 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-039 — useFetch #39

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 107 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-040 — useFetch #40

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 120 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-041 — useFetch #41

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 133 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-042 — useFetch #42

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 146 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-043 — useFetch #43

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 159 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-044 — useFetch #44

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 172 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-045 — useFetch #45

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 185 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-046 — useFetch #46

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 198 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-047 — useFetch #47

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 11 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-048 — useFetch #48

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 24 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-049 — useFetch #49

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 37 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-050 — useFetch #50

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 50 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-051 — useFetch #51

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 63 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-052 — useFetch #52

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 76 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-053 — useFetch #53

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 89 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-054 — useFetch #54

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 102 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-055 — useFetch #55

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 115 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-056 — useFetch #56

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 128 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-057 — useFetch #57

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 141 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-058 — useFetch #58

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 154 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-059 — useFetch #59

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 167 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-060 — useFetch #60

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 180 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-061 — useFetch #61

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 193 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-062 — useFetch #62

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 6 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-063 — useFetch #63

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 19 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-064 — useFetch #64

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 32 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-065 — useFetch #65

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 45 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-066 — useFetch #66

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 58 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-067 — useFetch #67

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 71 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-068 — useFetch #68

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 84 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-069 — useFetch #69

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 97 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-070 — useFetch #70

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 110 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-071 — useFetch #71

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 123 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-072 — useFetch #72

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 136 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-073 — useFetch #73

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 149 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-074 — useFetch #74

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 162 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-075 — useFetch #75

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 175 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-076 — useFetch #76

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 188 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-077 — useFetch #77

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 1 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-078 — useFetch #78

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 14 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-079 — useFetch #79

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 27 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-080 — useFetch #80

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 40 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-081 — useFetch #81

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 53 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-082 — useFetch #82

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 66 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-083 — useFetch #83

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 79 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-084 — useFetch #84

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 92 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-085 — useFetch #85

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 105 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-086 — useFetch #86

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 118 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-087 — useFetch #87

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 131 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-088 — useFetch #88

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 144 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-089 — useFetch #89

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 157 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-090 — useFetch #90

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 170 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-091 — useFetch #91

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 183 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-092 — useFetch #92

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 196 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-093 — useFetch #93

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 9 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-094 — useFetch #94

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 22 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-095 — useFetch #95

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 35 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-096 — useFetch #96

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 48 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-097 — useFetch #97

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 61 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-098 — useFetch #98

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 74 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-099 — useFetch #99

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 87 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-100 — useFetch #100

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 100 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-101 — useFetch #101

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 113 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-102 — useFetch #102

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 126 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-103 — useFetch #103

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 139 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-104 — useFetch #104

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 152 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-105 — useFetch #105

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 165 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-106 — useFetch #106

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 178 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-107 — useFetch #107

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 191 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-108 — useFetch #108

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 4 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-109 — useFetch #109

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 17 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-110 — useFetch #110

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 30 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-111 — useFetch #111

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 43 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-112 — useFetch #112

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 56 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-113 — useFetch #113

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 69 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-114 — useFetch #114

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 82 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-115 — useFetch #115

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 95 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-116 — useFetch #116

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 108 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-117 — useFetch #117

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 121 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-118 — useFetch #118

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 134 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-119 — useFetch #119

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 147 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-120 — useFetch #120

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 160 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-121 — useFetch #121

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 173 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-122 — useFetch #122

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 186 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-123 — useFetch #123

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 199 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-124 — useFetch #124

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 12 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-125 — useFetch #125

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 25 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-126 — useFetch #126

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 38 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-127 — useFetch #127

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 51 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-128 — useFetch #128

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 64 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-129 — useFetch #129

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 77 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-130 — useFetch #130

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 90 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-131 — useFetch #131

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 103 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-132 — useFetch #132

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 116 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-133 — useFetch #133

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 129 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-134 — useFetch #134

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 142 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-135 — useFetch #135

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 155 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-136 — useFetch #136

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 168 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-137 — useFetch #137

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 181 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-138 — useFetch #138

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 194 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-139 — useFetch #139

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 7 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-140 — useFetch #140

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 20 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-141 — useFetch #141

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 33 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-142 — useFetch #142

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 46 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-143 — useFetch #143

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 59 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-144 — useFetch #144

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 72 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-145 — useFetch #145

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 85 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-146 — useFetch #146

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 98 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-147 — useFetch #147

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 111 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-148 — useFetch #148

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 124 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-149 — useFetch #149

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 137 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-150 — useFetch #150

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 150 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-151 — useFetch #151

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 163 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-152 — useFetch #152

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 176 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-153 — useFetch #153

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 189 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-154 — useFetch #154

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 2 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-155 — useFetch #155

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 15 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-156 — useFetch #156

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 28 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-157 — useFetch #157

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 41 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-158 — useFetch #158

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 54 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-159 — useFetch #159

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 67 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-160 — useFetch #160

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 80 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-161 — useFetch #161

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 93 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Hook fetches inside render path accidentally (illegal).
  • Primary remediation: Migrate hot paths to TanStack Query; keep useFetch for teaching/simple cases.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-162 — useFetch #162

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 106 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Returned refetch not stable causing child memo churn.
  • Primary remediation: try/catch parse; map to typed error.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-163 — useFetch #163

  • Level: Beginner
  • Symptom: duplicate useEffect blocks across 119 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Caching attempted manually in hook conflicting with TanStack Query later.
  • Primary remediation: Only fetch from useEffect or event handlers.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-164 — useFetch #164

  • Level: Beginner+
  • Symptom: duplicate useEffect blocks across 132 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: GET dedupe absent; StrictMode double mount duplicates requests in dev.
  • Primary remediation: Document StrictMode; dedupe with query library or in-flight map.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-165 — useFetch #165

  • Level: Intermediate
  • Symptom: duplicate useEffect blocks across 145 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: URL in dependency array unstable object recreated each render.
  • Primary remediation: Return { data, error, status, code } discriminated model.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-166 — useFetch #166

  • Level: Intermediate+
  • Symptom: duplicate useEffect blocks across 158 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: JSON parse throws uncaught; hook never reaches error state.
  • Primary remediation: Wrap refetch in useCallback with stable deps.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-167 — useFetch #167

  • Level: Advanced
  • Symptom: duplicate useEffect blocks across 171 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: Errors surfaced as strings only; no status code for retry policy.
  • Primary remediation: Serialize deps ([url] string) or use primitive deps only.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

CH1-168 — useFetch #168

  • Level: Advanced+
  • Symptom: duplicate useEffect blocks across 184 screens or flaky tests after hook refactor.
  • Maintainability smell: hook name does not match behavior; grep fails.
  • Root cause class: useFetch missing AbortController races user navigation.
  • Primary remediation: Abort on dependency change + unmount; document cancellation semantics.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: A teaching useFetch shows effects + cancellation; production apps often adopt a cache library for dedupe and retries.

<< 2.9 Overview