Episode 2 — React Frontend Architecture NextJS / 2.13 — Global State Management
2.13.c — Zustand: lightweight alternative to heavy Redux
Learning outcomes
- Create a Zustand store with typed state and actions.
- Compare Zustand to Context and Redux on complexity and debuggability.
- Avoid common pitfalls (selector stability, persistence, SSR).
Hello store
import { create } from "zustand";
type BearState = {
bears: number;
increase: () => void;
};
export const useBearStore = create<BearState>((set) => ({
bears: 0,
increase: () => set((state) => ({ bears: state.bears + 1 })),
}));
export function BearCounter() {
const bears = useBearStore((s) => s.bears);
const increase = useBearStore((s) => s.increase);
return (
<button type="button" onClick={increase}>
{bears} bears
</button>
);
}
When Zustand often wins
- Medium shared client state without needing Redux DevTools time-travel everywhere.
- Teams wanting minimal boilerplate with good React subscription ergonomics.
When Redux might still win
- Large org needs strict action logs, replay tooling, and standardized middleware pipelines.
- Heavy cross-team governance already built around Redux Toolkit.
Appendix — Scenario bank (basic → advanced)
Each card: symptom → cause → fix → interview phrase. Drill five cards daily and explain aloud without reading.
GS2-001 — Zustand #1
- Level: Beginner
- Symptom: subtree re-renders
13% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-002 — Zustand #2
- Level: Beginner+
- Symptom: subtree re-renders
26% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-003 — Zustand #3
- Level: Intermediate
- Symptom: subtree re-renders
39% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-004 — Zustand #4
- Level: Intermediate+
- Symptom: subtree re-renders
52% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-005 — Zustand #5
- Level: Advanced
- Symptom: subtree re-renders
65% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-006 — Zustand #6
- Level: Advanced+
- Symptom: subtree re-renders
78% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-007 — Zustand #7
- Level: Beginner
- Symptom: subtree re-renders
91% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-008 — Zustand #8
- Level: Beginner+
- Symptom: subtree re-renders
104% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-009 — Zustand #9
- Level: Intermediate
- Symptom: subtree re-renders
117% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-010 — Zustand #10
- Level: Intermediate+
- Symptom: subtree re-renders
130% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-011 — Zustand #11
- Level: Advanced
- Symptom: subtree re-renders
143% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-012 — Zustand #12
- Level: Advanced+
- Symptom: subtree re-renders
156% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-013 — Zustand #13
- Level: Beginner
- Symptom: subtree re-renders
169% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-014 — Zustand #14
- Level: Beginner+
- Symptom: subtree re-renders
182% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-015 — Zustand #15
- Level: Intermediate
- Symptom: subtree re-renders
195% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-016 — Zustand #16
- Level: Intermediate+
- Symptom: subtree re-renders
8% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-017 — Zustand #17
- Level: Advanced
- Symptom: subtree re-renders
21% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-018 — Zustand #18
- Level: Advanced+
- Symptom: subtree re-renders
34% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-019 — Zustand #19
- Level: Beginner
- Symptom: subtree re-renders
47% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-020 — Zustand #20
- Level: Beginner+
- Symptom: subtree re-renders
60% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-021 — Zustand #21
- Level: Intermediate
- Symptom: subtree re-renders
73% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-022 — Zustand #22
- Level: Intermediate+
- Symptom: subtree re-renders
86% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-023 — Zustand #23
- Level: Advanced
- Symptom: subtree re-renders
99% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-024 — Zustand #24
- Level: Advanced+
- Symptom: subtree re-renders
112% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-025 — Zustand #25
- Level: Beginner
- Symptom: subtree re-renders
125% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-026 — Zustand #26
- Level: Beginner+
- Symptom: subtree re-renders
138% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-027 — Zustand #27
- Level: Intermediate
- Symptom: subtree re-renders
151% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-028 — Zustand #28
- Level: Intermediate+
- Symptom: subtree re-renders
164% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-029 — Zustand #29
- Level: Advanced
- Symptom: subtree re-renders
177% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-030 — Zustand #30
- Level: Advanced+
- Symptom: subtree re-renders
190% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-031 — Zustand #31
- Level: Beginner
- Symptom: subtree re-renders
3% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-032 — Zustand #32
- Level: Beginner+
- Symptom: subtree re-renders
16% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-033 — Zustand #33
- Level: Intermediate
- Symptom: subtree re-renders
29% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-034 — Zustand #34
- Level: Intermediate+
- Symptom: subtree re-renders
42% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-035 — Zustand #35
- Level: Advanced
- Symptom: subtree re-renders
55% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-036 — Zustand #36
- Level: Advanced+
- Symptom: subtree re-renders
68% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-037 — Zustand #37
- Level: Beginner
- Symptom: subtree re-renders
81% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-038 — Zustand #38
- Level: Beginner+
- Symptom: subtree re-renders
94% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-039 — Zustand #39
- Level: Intermediate
- Symptom: subtree re-renders
107% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-040 — Zustand #40
- Level: Intermediate+
- Symptom: subtree re-renders
120% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-041 — Zustand #41
- Level: Advanced
- Symptom: subtree re-renders
133% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-042 — Zustand #42
- Level: Advanced+
- Symptom: subtree re-renders
146% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-043 — Zustand #43
- Level: Beginner
- Symptom: subtree re-renders
159% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-044 — Zustand #44
- Level: Beginner+
- Symptom: subtree re-renders
172% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-045 — Zustand #45
- Level: Intermediate
- Symptom: subtree re-renders
185% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-046 — Zustand #46
- Level: Intermediate+
- Symptom: subtree re-renders
198% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-047 — Zustand #47
- Level: Advanced
- Symptom: subtree re-renders
11% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-048 — Zustand #48
- Level: Advanced+
- Symptom: subtree re-renders
24% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-049 — Zustand #49
- Level: Beginner
- Symptom: subtree re-renders
37% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-050 — Zustand #50
- Level: Beginner+
- Symptom: subtree re-renders
50% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-051 — Zustand #51
- Level: Intermediate
- Symptom: subtree re-renders
63% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-052 — Zustand #52
- Level: Intermediate+
- Symptom: subtree re-renders
76% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-053 — Zustand #53
- Level: Advanced
- Symptom: subtree re-renders
89% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-054 — Zustand #54
- Level: Advanced+
- Symptom: subtree re-renders
102% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-055 — Zustand #55
- Level: Beginner
- Symptom: subtree re-renders
115% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-056 — Zustand #56
- Level: Beginner+
- Symptom: subtree re-renders
128% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-057 — Zustand #57
- Level: Intermediate
- Symptom: subtree re-renders
141% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-058 — Zustand #58
- Level: Intermediate+
- Symptom: subtree re-renders
154% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-059 — Zustand #59
- Level: Advanced
- Symptom: subtree re-renders
167% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-060 — Zustand #60
- Level: Advanced+
- Symptom: subtree re-renders
180% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-061 — Zustand #61
- Level: Beginner
- Symptom: subtree re-renders
193% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-062 — Zustand #62
- Level: Beginner+
- Symptom: subtree re-renders
6% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-063 — Zustand #63
- Level: Intermediate
- Symptom: subtree re-renders
19% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-064 — Zustand #64
- Level: Intermediate+
- Symptom: subtree re-renders
32% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-065 — Zustand #65
- Level: Advanced
- Symptom: subtree re-renders
45% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-066 — Zustand #66
- Level: Advanced+
- Symptom: subtree re-renders
58% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-067 — Zustand #67
- Level: Beginner
- Symptom: subtree re-renders
71% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-068 — Zustand #68
- Level: Beginner+
- Symptom: subtree re-renders
84% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-069 — Zustand #69
- Level: Intermediate
- Symptom: subtree re-renders
97% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-070 — Zustand #70
- Level: Intermediate+
- Symptom: subtree re-renders
110% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-071 — Zustand #71
- Level: Advanced
- Symptom: subtree re-renders
123% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-072 — Zustand #72
- Level: Advanced+
- Symptom: subtree re-renders
136% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-073 — Zustand #73
- Level: Beginner
- Symptom: subtree re-renders
149% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-074 — Zustand #74
- Level: Beginner+
- Symptom: subtree re-renders
162% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-075 — Zustand #75
- Level: Intermediate
- Symptom: subtree re-renders
175% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-076 — Zustand #76
- Level: Intermediate+
- Symptom: subtree re-renders
188% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-077 — Zustand #77
- Level: Advanced
- Symptom: subtree re-renders
1% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-078 — Zustand #78
- Level: Advanced+
- Symptom: subtree re-renders
14% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-079 — Zustand #79
- Level: Beginner
- Symptom: subtree re-renders
27% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-080 — Zustand #80
- Level: Beginner+
- Symptom: subtree re-renders
40% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-081 — Zustand #81
- Level: Intermediate
- Symptom: subtree re-renders
53% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-082 — Zustand #82
- Level: Intermediate+
- Symptom: subtree re-renders
66% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-083 — Zustand #83
- Level: Advanced
- Symptom: subtree re-renders
79% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-084 — Zustand #84
- Level: Advanced+
- Symptom: subtree re-renders
92% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-085 — Zustand #85
- Level: Beginner
- Symptom: subtree re-renders
105% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-086 — Zustand #86
- Level: Beginner+
- Symptom: subtree re-renders
118% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-087 — Zustand #87
- Level: Intermediate
- Symptom: subtree re-renders
131% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-088 — Zustand #88
- Level: Intermediate+
- Symptom: subtree re-renders
144% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-089 — Zustand #89
- Level: Advanced
- Symptom: subtree re-renders
157% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-090 — Zustand #90
- Level: Advanced+
- Symptom: subtree re-renders
170% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-091 — Zustand #91
- Level: Beginner
- Symptom: subtree re-renders
183% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-092 — Zustand #92
- Level: Beginner+
- Symptom: subtree re-renders
196% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-093 — Zustand #93
- Level: Intermediate
- Symptom: subtree re-renders
9% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-094 — Zustand #94
- Level: Intermediate+
- Symptom: subtree re-renders
22% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-095 — Zustand #95
- Level: Advanced
- Symptom: subtree re-renders
35% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-096 — Zustand #96
- Level: Advanced+
- Symptom: subtree re-renders
48% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-097 — Zustand #97
- Level: Beginner
- Symptom: subtree re-renders
61% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-098 — Zustand #98
- Level: Beginner+
- Symptom: subtree re-renders
74% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-099 — Zustand #99
- Level: Intermediate
- Symptom: subtree re-renders
87% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-100 — Zustand #100
- Level: Intermediate+
- Symptom: subtree re-renders
100% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-101 — Zustand #101
- Level: Advanced
- Symptom: subtree re-renders
113% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-102 — Zustand #102
- Level: Advanced+
- Symptom: subtree re-renders
126% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-103 — Zustand #103
- Level: Beginner
- Symptom: subtree re-renders
139% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-104 — Zustand #104
- Level: Beginner+
- Symptom: subtree re-renders
152% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-105 — Zustand #105
- Level: Intermediate
- Symptom: subtree re-renders
165% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-106 — Zustand #106
- Level: Intermediate+
- Symptom: subtree re-renders
178% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-107 — Zustand #107
- Level: Advanced
- Symptom: subtree re-renders
191% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-108 — Zustand #108
- Level: Advanced+
- Symptom: subtree re-renders
4% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-109 — Zustand #109
- Level: Beginner
- Symptom: subtree re-renders
17% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-110 — Zustand #110
- Level: Beginner+
- Symptom: subtree re-renders
30% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-111 — Zustand #111
- Level: Intermediate
- Symptom: subtree re-renders
43% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-112 — Zustand #112
- Level: Intermediate+
- Symptom: subtree re-renders
56% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-113 — Zustand #113
- Level: Advanced
- Symptom: subtree re-renders
69% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-114 — Zustand #114
- Level: Advanced+
- Symptom: subtree re-renders
82% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-115 — Zustand #115
- Level: Beginner
- Symptom: subtree re-renders
95% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-116 — Zustand #116
- Level: Beginner+
- Symptom: subtree re-renders
108% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-117 — Zustand #117
- Level: Intermediate
- Symptom: subtree re-renders
121% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-118 — Zustand #118
- Level: Intermediate+
- Symptom: subtree re-renders
134% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-119 — Zustand #119
- Level: Advanced
- Symptom: subtree re-renders
147% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-120 — Zustand #120
- Level: Advanced+
- Symptom: subtree re-renders
160% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-121 — Zustand #121
- Level: Beginner
- Symptom: subtree re-renders
173% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-122 — Zustand #122
- Level: Beginner+
- Symptom: subtree re-renders
186% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-123 — Zustand #123
- Level: Intermediate
- Symptom: subtree re-renders
199% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-124 — Zustand #124
- Level: Intermediate+
- Symptom: subtree re-renders
12% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-125 — Zustand #125
- Level: Advanced
- Symptom: subtree re-renders
25% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-126 — Zustand #126
- Level: Advanced+
- Symptom: subtree re-renders
38% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-127 — Zustand #127
- Level: Beginner
- Symptom: subtree re-renders
51% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-128 — Zustand #128
- Level: Beginner+
- Symptom: subtree re-renders
64% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-129 — Zustand #129
- Level: Intermediate
- Symptom: subtree re-renders
77% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-130 — Zustand #130
- Level: Intermediate+
- Symptom: subtree re-renders
90% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-131 — Zustand #131
- Level: Advanced
- Symptom: subtree re-renders
103% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-132 — Zustand #132
- Level: Advanced+
- Symptom: subtree re-renders
116% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-133 — Zustand #133
- Level: Beginner
- Symptom: subtree re-renders
129% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-134 — Zustand #134
- Level: Beginner+
- Symptom: subtree re-renders
142% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-135 — Zustand #135
- Level: Intermediate
- Symptom: subtree re-renders
155% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-136 — Zustand #136
- Level: Intermediate+
- Symptom: subtree re-renders
168% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-137 — Zustand #137
- Level: Advanced
- Symptom: subtree re-renders
181% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-138 — Zustand #138
- Level: Advanced+
- Symptom: subtree re-renders
194% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-139 — Zustand #139
- Level: Beginner
- Symptom: subtree re-renders
7% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-140 — Zustand #140
- Level: Beginner+
- Symptom: subtree re-renders
20% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-141 — Zustand #141
- Level: Intermediate
- Symptom: subtree re-renders
33% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-142 — Zustand #142
- Level: Intermediate+
- Symptom: subtree re-renders
46% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-143 — Zustand #143
- Level: Advanced
- Symptom: subtree re-renders
59% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-144 — Zustand #144
- Level: Advanced+
- Symptom: subtree re-renders
72% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-145 — Zustand #145
- Level: Beginner
- Symptom: subtree re-renders
85% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-146 — Zustand #146
- Level: Beginner+
- Symptom: subtree re-renders
98% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-147 — Zustand #147
- Level: Intermediate
- Symptom: subtree re-renders
111% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-148 — Zustand #148
- Level: Intermediate+
- Symptom: subtree re-renders
124% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-149 — Zustand #149
- Level: Advanced
- Symptom: subtree re-renders
137% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-150 — Zustand #150
- Level: Advanced+
- Symptom: subtree re-renders
150% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-151 — Zustand #151
- Level: Beginner
- Symptom: subtree re-renders
163% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-152 — Zustand #152
- Level: Beginner+
- Symptom: subtree re-renders
176% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-153 — Zustand #153
- Level: Intermediate
- Symptom: subtree re-renders
189% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: SSR hydration mismatch because client-only default differs from server snapshot.
- Primary remediation: Gate client defaults behind useEffect or align SSR snapshot with same initial state.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-154 — Zustand #154
- Level: Intermediate+
- Symptom: subtree re-renders
2% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Persist middleware misused storing sensitive tokens in localStorage.
- Primary remediation: Export singleton store from module scope; document HMR patterns.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-155 — Zustand #155
- Level: Advanced
- Symptom: subtree re-renders
15% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Selectors return new objects each call causing unnecessary React updates.
- Primary remediation: Extract pure reducers/helpers testable without React.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-156 — Zustand #156
- Level: Advanced+
- Symptom: subtree re-renders
28% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Store becomes a junk drawer of unrelated keys with no module ownership.
- Primary remediation: Partition stores or use slices with clear names; enforce ADR ownership per slice.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-157 — Zustand #157
- Level: Beginner
- Symptom: subtree re-renders
41% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Business rules embedded in setter lambdas without tests.
- Primary remediation: Use shallow compare or return primitives from selectors; use
useShallowwhen appropriate. - Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.
GS2-158 — Zustand #158
- Level: Beginner+
- Symptom: subtree re-renders
54% more than expected after a small unrelated UI change. - Architecture smell: unclear ownership of who may mutate shared state.
- Root cause class: Multiple store instances created accidentally in dev strict or HMR edge cases.
- Primary remediation: Never persist secrets; whitelist keys; encrypt only when product requires and experts agree.
- Proof: React DevTools highlight updates; split providers and re-measure.
- Interview one-liner: Zustand trades ceremony for discipline—you still need boundaries and conventions.