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

2.9.a — Why custom hooks exist: extracting shared logic

<< 2.9 Overview


Learning outcomes

  1. State the problem custom hooks solve compared to plain functions or class patterns.
  2. Apply the Rules of Hooks to hooks you author.
  3. Decide when a custom hook beats a utility function or context.

The core idea

A custom hook is a JavaScript function whose name starts with use and that may call other hooks. It lets you reuse stateful logic across components without changing the component tree structure (unlike render props/HOCs for some cases).

import { useCallback, useState } from "react";

export function useCounter(initial = 0) {
  const [count, setCount] = useState(initial);
  const inc = useCallback(() => setCount((c) => c + 1), []);
  return { count, inc };
}

Rules of Hooks (authoring perspective)

  1. Only call hooks at the top level of your custom hook (not inside loops/conditions unless those conditions never change hook order incorrectly—prefer avoiding).
  2. Only call hooks from React functions (components or custom hooks).

When not to create a hook

If logic is pure (no state, no effects), a plain calculateTotals(items) module is simpler.


Hooks vs context

Use context when many distant consumers need the same live value. Use a custom hook to bundle related state+actions that might still be created per subtree or passed as composition.



Appendix — Scenario bank (basic → advanced)

Flashcard: symptom → cause → fix → interview phrase.

CH0-001 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-002 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-003 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-004 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-005 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-006 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-007 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-008 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-009 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-010 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-011 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-012 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-013 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-014 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-015 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-016 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-017 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-018 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-019 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-020 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-021 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-022 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-023 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-024 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-025 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-026 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-027 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-028 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-029 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-030 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-031 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-032 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-033 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-034 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-035 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-036 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-037 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-038 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-039 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-040 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-041 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-042 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-043 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-044 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-045 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-046 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-047 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-048 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-049 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-050 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-051 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-052 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-053 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-054 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-055 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-056 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-057 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-058 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-059 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-060 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-061 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-062 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-063 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-064 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-065 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-066 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-067 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-068 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-069 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-070 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-071 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-072 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-073 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-074 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-075 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-076 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-077 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-078 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-079 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-080 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-081 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-082 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-083 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-084 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-085 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-086 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-087 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-088 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-089 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-090 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-091 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-092 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-093 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-094 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-095 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-096 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-097 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-098 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-099 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-100 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-101 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-102 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-103 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-104 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-105 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-106 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-107 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-108 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-109 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-110 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-111 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-112 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-113 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-114 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-115 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-116 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-117 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-118 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-119 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-120 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-121 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-122 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-123 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-124 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-125 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-126 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-127 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-128 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-129 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-130 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-131 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-132 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-133 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-134 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-135 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-136 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-137 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-138 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-139 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-140 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-141 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-142 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-143 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-144 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-145 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-146 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-147 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-148 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-149 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-150 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-151 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-152 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-153 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-154 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-155 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-156 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-157 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-158 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-159 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-160 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-161 — Why hooks #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: Two hooks mutate same global module variable (hidden coupling).
  • Primary remediation: Add light RFC for shared hooks folder conventions.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-162 — Why hooks #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: Conditional hook call inside custom hook helper function.
  • Primary remediation: Version return object with documented fields; prefer small objects over huge bags.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-163 — Why hooks #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: Team invents hook for every 5 lines without design discussion.
  • Primary remediation: Pass dependencies explicitly; avoid module singletons for feature state.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-164 — Why hooks #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: Hook used only once—premature abstraction.
  • Primary remediation: Wait for second usage or extract pure function instead.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-165 — Why hooks #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: God hook returns 40 unrelated fields used by one screen each.
  • Primary remediation: Extract shared useAbortable or document cleanup contract.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-166 — Why hooks #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: Hook API unstable: return shape changes every PR breaking consumers.
  • Primary remediation: Refactor to unconditional hook paths; lift condition to caller.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-167 — Why hooks #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: Copy-paste hook without extracting shared cleanup (memory leak).
  • Primary remediation: Split into useInvoiceList + useInvoiceActions with cohesive return types.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

CH0-168 — Why hooks #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: Custom hook is just a function without use prefix but calls hooks—confusing and breaks lint rules.
  • Primary remediation: Name hooks useThing; only call hooks at top level of hook or component.
  • Verify: RTL hook test + one story + bundle diff if heavy.
  • Interview one-liner: Custom hooks exist to reuse stateful logic while obeying the Rules of Hooks—composition without wrapper components.

<< 2.9 Overview