Episode 2 — React Frontend Architecture NextJS / 2.15 — Advanced Forms and Validation
2.15.b — Controlled vs uncontrolled forms
Learning outcomes
- Choose controlled vs uncontrolled confidently with UX and performance reasoning.
- Avoid mixed-mode bugs (
value+defaultValue). - Handle special inputs: files, checkboxes, contenteditable edges.
Controlled inputs
React owns the value:
import { useState } from "react";
export function Controlled() {
const [name, setName] = useState("");
return <input value={name} onChange={(e) => setName(e.target.value)} />;
}
Pros: easy to derive UI, validate on each change, enforce masks.
Cons: parent re-renders can get expensive if state lives too high.
Uncontrolled inputs
The DOM owns the value; React sets initial via defaultValue:
export function Uncontrolled() {
return <input name="title" defaultValue="Draft" />;
}
Pros: fewer React updates; great for large forms when combined with submit-time validation.
Cons: harder to drive purely from props for highly dynamic external constraints.
The mixed-mode footgun
Do not do:
<input value={x} defaultValue={y} />
Pick one. If you need to reset, use a key or explicit RHF reset.
When controlled is the right default
- Tightly coupled UI: sliders with live previews, masked inputs, multi-field dependent validation shown continuously.
- You must reflect external updates (server-driven field overrides) while user is editing—careful merge strategies required.
When uncontrolled / RHF wins
- Large forms with many fields and few cross-field live constraints.
- Performance-sensitive pages where per-keystroke parent renders are measurable.
FormData and progressive enhancement
Native uncontrolled forms can submit without JS. Even if you rely on JS, understanding FormData helps integrate with server actions and endpoints.
Appendix — Scenario bank (basic → advanced)
Each scenario is a mini design review: what users see, what breaks, what you change, what you say in an interview. Cover five per day and narrate fixes out loud.
CU-001 — Controlled vs uncontrolled scenario #1
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
13 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-002 — Controlled vs uncontrolled scenario #2
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
26 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-003 — Controlled vs uncontrolled scenario #3
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
39 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-004 — Controlled vs uncontrolled scenario #4
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
52 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-005 — Controlled vs uncontrolled scenario #5
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
65 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-006 — Controlled vs uncontrolled scenario #6
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
78 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-007 — Controlled vs uncontrolled scenario #7
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
91 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-008 — Controlled vs uncontrolled scenario #8
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
104 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-009 — Controlled vs uncontrolled scenario #9
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
117 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-010 — Controlled vs uncontrolled scenario #10
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
10 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-011 — Controlled vs uncontrolled scenario #11
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
23 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-012 — Controlled vs uncontrolled scenario #12
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
36 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-013 — Controlled vs uncontrolled scenario #13
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
49 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-014 — Controlled vs uncontrolled scenario #14
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
62 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-015 — Controlled vs uncontrolled scenario #15
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
75 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-016 — Controlled vs uncontrolled scenario #16
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
88 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-017 — Controlled vs uncontrolled scenario #17
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
101 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-018 — Controlled vs uncontrolled scenario #18
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
114 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-019 — Controlled vs uncontrolled scenario #19
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
7 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-020 — Controlled vs uncontrolled scenario #20
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
20 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-021 — Controlled vs uncontrolled scenario #21
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
33 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-022 — Controlled vs uncontrolled scenario #22
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
46 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-023 — Controlled vs uncontrolled scenario #23
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
59 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-024 — Controlled vs uncontrolled scenario #24
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
72 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-025 — Controlled vs uncontrolled scenario #25
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
85 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-026 — Controlled vs uncontrolled scenario #26
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
98 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-027 — Controlled vs uncontrolled scenario #27
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
111 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-028 — Controlled vs uncontrolled scenario #28
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
4 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-029 — Controlled vs uncontrolled scenario #29
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
17 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-030 — Controlled vs uncontrolled scenario #30
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
30 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-031 — Controlled vs uncontrolled scenario #31
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
43 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-032 — Controlled vs uncontrolled scenario #32
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
56 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-033 — Controlled vs uncontrolled scenario #33
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
69 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-034 — Controlled vs uncontrolled scenario #34
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
82 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-035 — Controlled vs uncontrolled scenario #35
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
95 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-036 — Controlled vs uncontrolled scenario #36
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
108 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-037 — Controlled vs uncontrolled scenario #37
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
1 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-038 — Controlled vs uncontrolled scenario #38
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
14 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-039 — Controlled vs uncontrolled scenario #39
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
27 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-040 — Controlled vs uncontrolled scenario #40
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
40 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-041 — Controlled vs uncontrolled scenario #41
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
53 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-042 — Controlled vs uncontrolled scenario #42
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
66 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-043 — Controlled vs uncontrolled scenario #43
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
79 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-044 — Controlled vs uncontrolled scenario #44
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
92 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-045 — Controlled vs uncontrolled scenario #45
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
105 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-046 — Controlled vs uncontrolled scenario #46
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
118 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-047 — Controlled vs uncontrolled scenario #47
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
11 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-048 — Controlled vs uncontrolled scenario #48
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
24 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-049 — Controlled vs uncontrolled scenario #49
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
37 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-050 — Controlled vs uncontrolled scenario #50
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
50 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-051 — Controlled vs uncontrolled scenario #51
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
63 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-052 — Controlled vs uncontrolled scenario #52
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
76 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-053 — Controlled vs uncontrolled scenario #53
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
89 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-054 — Controlled vs uncontrolled scenario #54
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
102 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-055 — Controlled vs uncontrolled scenario #55
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
115 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-056 — Controlled vs uncontrolled scenario #56
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
8 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-057 — Controlled vs uncontrolled scenario #57
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
21 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-058 — Controlled vs uncontrolled scenario #58
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
34 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-059 — Controlled vs uncontrolled scenario #59
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
47 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-060 — Controlled vs uncontrolled scenario #60
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
60 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-061 — Controlled vs uncontrolled scenario #61
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
73 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-062 — Controlled vs uncontrolled scenario #62
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
86 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-063 — Controlled vs uncontrolled scenario #63
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
99 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-064 — Controlled vs uncontrolled scenario #64
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
112 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-065 — Controlled vs uncontrolled scenario #65
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
5 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-066 — Controlled vs uncontrolled scenario #66
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
18 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-067 — Controlled vs uncontrolled scenario #67
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
31 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-068 — Controlled vs uncontrolled scenario #68
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
44 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-069 — Controlled vs uncontrolled scenario #69
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
57 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-070 — Controlled vs uncontrolled scenario #70
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
70 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-071 — Controlled vs uncontrolled scenario #71
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
83 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-072 — Controlled vs uncontrolled scenario #72
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
96 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-073 — Controlled vs uncontrolled scenario #73
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
109 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-074 — Controlled vs uncontrolled scenario #74
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
2 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-075 — Controlled vs uncontrolled scenario #75
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
15 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-076 — Controlled vs uncontrolled scenario #76
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
28 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-077 — Controlled vs uncontrolled scenario #77
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
41 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-078 — Controlled vs uncontrolled scenario #78
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
54 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-079 — Controlled vs uncontrolled scenario #79
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
67 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-080 — Controlled vs uncontrolled scenario #80
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
80 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-081 — Controlled vs uncontrolled scenario #81
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
93 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-082 — Controlled vs uncontrolled scenario #82
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
106 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-083 — Controlled vs uncontrolled scenario #83
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
119 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-084 — Controlled vs uncontrolled scenario #84
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
12 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-085 — Controlled vs uncontrolled scenario #85
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
25 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-086 — Controlled vs uncontrolled scenario #86
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
38 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-087 — Controlled vs uncontrolled scenario #87
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
51 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-088 — Controlled vs uncontrolled scenario #88
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
64 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-089 — Controlled vs uncontrolled scenario #89
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
77 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-090 — Controlled vs uncontrolled scenario #90
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
90 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-091 — Controlled vs uncontrolled scenario #91
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
103 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-092 — Controlled vs uncontrolled scenario #92
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
116 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-093 — Controlled vs uncontrolled scenario #93
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
9 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-094 — Controlled vs uncontrolled scenario #94
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
22 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-095 — Controlled vs uncontrolled scenario #95
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
35 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-096 — Controlled vs uncontrolled scenario #96
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
48 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-097 — Controlled vs uncontrolled scenario #97
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
61 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-098 — Controlled vs uncontrolled scenario #98
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
74 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-099 — Controlled vs uncontrolled scenario #99
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
87 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-100 — Controlled vs uncontrolled scenario #100
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
100 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-101 — Controlled vs uncontrolled scenario #101
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
113 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-102 — Controlled vs uncontrolled scenario #102
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
6 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-103 — Controlled vs uncontrolled scenario #103
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
19 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-104 — Controlled vs uncontrolled scenario #104
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
32 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-105 — Controlled vs uncontrolled scenario #105
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
45 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-106 — Controlled vs uncontrolled scenario #106
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
58 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-107 — Controlled vs uncontrolled scenario #107
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
71 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-108 — Controlled vs uncontrolled scenario #108
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
84 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-109 — Controlled vs uncontrolled scenario #109
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
97 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-110 — Controlled vs uncontrolled scenario #110
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
110 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-111 — Controlled vs uncontrolled scenario #111
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
3 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-112 — Controlled vs uncontrolled scenario #112
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
16 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-113 — Controlled vs uncontrolled scenario #113
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
29 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-114 — Controlled vs uncontrolled scenario #114
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
42 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-115 — Controlled vs uncontrolled scenario #115
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
55 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-116 — Controlled vs uncontrolled scenario #116
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
68 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-117 — Controlled vs uncontrolled scenario #117
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
81 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-118 — Controlled vs uncontrolled scenario #118
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
94 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-119 — Controlled vs uncontrolled scenario #119
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
107 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-120 — Controlled vs uncontrolled scenario #120
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
0 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-121 — Controlled vs uncontrolled scenario #121
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
13 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-122 — Controlled vs uncontrolled scenario #122
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
26 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-123 — Controlled vs uncontrolled scenario #123
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
39 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-124 — Controlled vs uncontrolled scenario #124
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
52 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-125 — Controlled vs uncontrolled scenario #125
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
65 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-126 — Controlled vs uncontrolled scenario #126
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
78 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-127 — Controlled vs uncontrolled scenario #127
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
91 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-128 — Controlled vs uncontrolled scenario #128
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
104 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-129 — Controlled vs uncontrolled scenario #129
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
117 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-130 — Controlled vs uncontrolled scenario #130
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
10 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-131 — Controlled vs uncontrolled scenario #131
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
23 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-132 — Controlled vs uncontrolled scenario #132
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
36 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-133 — Controlled vs uncontrolled scenario #133
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
49 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-134 — Controlled vs uncontrolled scenario #134
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
62 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-135 — Controlled vs uncontrolled scenario #135
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
75 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-136 — Controlled vs uncontrolled scenario #136
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
88 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-137 — Controlled vs uncontrolled scenario #137
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
101 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-138 — Controlled vs uncontrolled scenario #138
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
114 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-139 — Controlled vs uncontrolled scenario #139
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
7 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-140 — Controlled vs uncontrolled scenario #140
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
20 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-141 — Controlled vs uncontrolled scenario #141
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
33 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-142 — Controlled vs uncontrolled scenario #142
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
46 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-143 — Controlled vs uncontrolled scenario #143
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
59 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-144 — Controlled vs uncontrolled scenario #144
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
72 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-145 — Controlled vs uncontrolled scenario #145
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
85 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-146 — Controlled vs uncontrolled scenario #146
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
98 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-147 — Controlled vs uncontrolled scenario #147
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
111 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-148 — Controlled vs uncontrolled scenario #148
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
4 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-149 — Controlled vs uncontrolled scenario #149
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
17 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-150 — Controlled vs uncontrolled scenario #150
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
30 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-151 — Controlled vs uncontrolled scenario #151
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
43 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-152 — Controlled vs uncontrolled scenario #152
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
56 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-153 — Controlled vs uncontrolled scenario #153
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
69 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Checkbox group implemented as multiple booleans instead of array model.
- Primary remediation: Gate client-only defaults behind
useEffector consistent SSR sources. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-154 — Controlled vs uncontrolled scenario #154
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
82 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Uncontrolled file input read incorrectly (missing refs or FormData discipline).
- Primary remediation: Wrap third-party widgets with Controller and documented value/onChange mapping.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-155 — Controlled vs uncontrolled scenario #155
- Level: Advanced
- User-visible symptom: validation flicker, double submit, or lost input after
95 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: SSR hydration mismatch due to differing initial values between server and client.
- Primary remediation: Model checkbox lists as
string[]with consistent naming. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-156 — Controlled vs uncontrolled scenario #156
- Level: Advanced+
- User-visible symptom: validation flicker, double submit, or lost input after
108 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Using key remount hacks to reset forms instead of explicit reset APIs.
- Primary remediation: Use explicit
resetfrom RHF or controlled state reset patterns with clear UX. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-157 — Controlled vs uncontrolled scenario #157
- Level: Beginner
- User-visible symptom: validation flicker, double submit, or lost input after
1 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Controlled form with huge parent state causing wide re-renders per keystroke.
- Primary remediation: Stabilize defaults; move expensive parents away from per-keystroke state if needed.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-158 — Controlled vs uncontrolled scenario #158
- Level: Beginner+
- User-visible symptom: validation flicker, double submit, or lost input after
14 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Third-party input only supports controlled mode; forced into heavy state updates.
- Primary remediation: Use
FormDatain submit handlers for uncontrolled native forms; validate server-side. - Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.
CU-159 — Controlled vs uncontrolled scenario #159
- Level: Intermediate
- User-visible symptom: validation flicker, double submit, or lost input after
27 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Derived default props recreate each render resetting user input unintentionally.
- Primary remediation: Lift only needed state; colocate heavy fields; consider RHF for registration model.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: DefaultValue is initial mount only; value is continuous control.
CU-160 — Controlled vs uncontrolled scenario #160
- Level: Intermediate+
- User-visible symptom: validation flicker, double submit, or lost input after
40 msasync checks. - Form architecture symptom: state thrashes, unnecessary renders, or impossible-to-test validation scattered in JSX.
- Root cause class: Mixing
valueanddefaultValueon the same input (controlled confusion). - Primary remediation: Pick one model per input; use key reset intentionally when switching modes.
- Accessibility check: associate errors with fields via
aria-describedby/aria-invalid; do not rely on color alone. - Interview one-liner: Controlled: React owns value; uncontrolled: DOM owns value—do not mix signals.