[{"data":1,"prerenderedAt":8220},["ShallowReactive",2],{"page-\u002Freact\u002F14-forms-controlled-and-uncontrolled":3},{"id":4,"title":5,"body":6,"description":8213,"extension":8214,"meta":8215,"navigation":57,"path":8216,"seo":8217,"stem":8218,"__hash__":8219},"content\u002Freact\u002F14-forms-controlled-and-uncontrolled.md","14 — Forms: Controlled & Uncontrolled",{"type":7,"value":8,"toc":8197},"minimark",[9,13,18,453,457,755,759,1399,1403,1987,1991,2831,2835,3251,3255,4032,4036,4521,4525,6242,6246,7446,7450,7562,7566,7707,7711,7716,7861,8078,8082,8193],[10,11,5],"h1",{"id":12},"_14-forms-controlled-uncontrolled",[14,15,17],"h2",{"id":16},"the-core-distinction","The Core Distinction",[19,20,23],"code-wrapper",{"filename":21,"language":22},"core_distinction.js","javascript",[24,25,29],"pre",{"className":26,"code":27,"language":22,"meta":28,"style":28},"language-javascript shiki shiki-themes github-light github-dark","import { useState, useRef, useReducer, useCallback } from 'react'\n\n\u002F\u002F Every HTML form element has its own internal DOM state (the browser tracks the\n\u002F\u002F value). In React, you must decide PER FIELD whether React or the DOM owns that state.\n\n\u002F\u002F ── CONTROLLED: React owns the value ──\n\u002F\u002F value={state} + onChange={update state} → React state is the single source of truth.\n\u002F\u002F Every keystroke: DOM → onChange → setState → re-render → value prop → DOM.\n\u002F\u002F The displayed value can never diverge from React state.\n\nfunction ControlledInput() {\n  const [email, setEmail] = useState('')\n  return (\n    \u003Cinput\n      type=\"email\"\n      value={email}\n      onChange={e => setEmail(e.target.value)}\n    \u002F>\n  )\n}\n\n\u002F\u002F ── UNCONTROLLED: the DOM owns the value ──\n\u002F\u002F defaultValue={initial} (set once on mount) + ref to read the value when needed.\n\u002F\u002F React does NOT control the value — the browser manages it as users type.\n\nfunction UncontrolledInput() {\n  const inputRef = useRef(null)\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    console.log(inputRef.current.value)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput type=\"text\" defaultValue=\"\" ref={inputRef} \u002F>\n      \u003Cbutton type=\"submit\">Submit\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n","",[30,31,32,52,59,66,72,77,83,89,95,101,106,119,156,165,175,186,197,221,227,233,239,244,250,256,262,267,277,298,303,319,331,343,349,354,361,377,410,433,443,448],"code",{"__ignoreMap":28},[33,34,37,41,45,48],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"svdQ7","import",[33,42,44],{"class":43},"ssxIu"," { useState, useRef, useReducer, useCallback } ",[33,46,47],{"class":39},"from",[33,49,51],{"class":50},"sJ6F3"," 'react'\n",[33,53,55],{"class":35,"line":54},2,[33,56,58],{"emptyLinePlaceholder":57},true,"\n",[33,60,62],{"class":35,"line":61},3,[33,63,65],{"class":64},"sdCPZ","\u002F\u002F Every HTML form element has its own internal DOM state (the browser tracks the\n",[33,67,69],{"class":35,"line":68},4,[33,70,71],{"class":64},"\u002F\u002F value). In React, you must decide PER FIELD whether React or the DOM owns that state.\n",[33,73,75],{"class":35,"line":74},5,[33,76,58],{"emptyLinePlaceholder":57},[33,78,80],{"class":35,"line":79},6,[33,81,82],{"class":64},"\u002F\u002F ── CONTROLLED: React owns the value ──\n",[33,84,86],{"class":35,"line":85},7,[33,87,88],{"class":64},"\u002F\u002F value={state} + onChange={update state} → React state is the single source of truth.\n",[33,90,92],{"class":35,"line":91},8,[33,93,94],{"class":64},"\u002F\u002F Every keystroke: DOM → onChange → setState → re-render → value prop → DOM.\n",[33,96,98],{"class":35,"line":97},9,[33,99,100],{"class":64},"\u002F\u002F The displayed value can never diverge from React state.\n",[33,102,104],{"class":35,"line":103},10,[33,105,58],{"emptyLinePlaceholder":57},[33,107,109,112,116],{"class":35,"line":108},11,[33,110,111],{"class":39},"function",[33,113,115],{"class":114},"sIsaT"," ControlledInput",[33,117,118],{"class":43},"() {\n",[33,120,122,125,128,132,135,138,141,144,147,150,153],{"class":35,"line":121},12,[33,123,124],{"class":39},"  const",[33,126,127],{"class":43}," [",[33,129,131],{"class":130},"snvgF","email",[33,133,134],{"class":43},", ",[33,136,137],{"class":130},"setEmail",[33,139,140],{"class":43},"] ",[33,142,143],{"class":39},"=",[33,145,146],{"class":114}," useState",[33,148,149],{"class":43},"(",[33,151,152],{"class":50},"''",[33,154,155],{"class":43},")\n",[33,157,159,162],{"class":35,"line":158},13,[33,160,161],{"class":39},"  return",[33,163,164],{"class":43}," (\n",[33,166,168,171],{"class":35,"line":167},14,[33,169,170],{"class":43},"    \u003C",[33,172,174],{"class":173},"sk71V","input\n",[33,176,178,181,183],{"class":35,"line":177},15,[33,179,180],{"class":114},"      type",[33,182,143],{"class":39},[33,184,185],{"class":50},"\"email\"\n",[33,187,189,192,194],{"class":35,"line":188},16,[33,190,191],{"class":114},"      value",[33,193,143],{"class":39},[33,195,196],{"class":43},"{email}\n",[33,198,200,203,205,208,212,215,218],{"class":35,"line":199},17,[33,201,202],{"class":114},"      onChange",[33,204,143],{"class":39},[33,206,207],{"class":43},"{",[33,209,211],{"class":210},"sCrzJ","e",[33,213,214],{"class":39}," =>",[33,216,217],{"class":114}," setEmail",[33,219,220],{"class":43},"(e.target.value)}\n",[33,222,224],{"class":35,"line":223},18,[33,225,226],{"class":43},"    \u002F>\n",[33,228,230],{"class":35,"line":229},19,[33,231,232],{"class":43},"  )\n",[33,234,236],{"class":35,"line":235},20,[33,237,238],{"class":43},"}\n",[33,240,242],{"class":35,"line":241},21,[33,243,58],{"emptyLinePlaceholder":57},[33,245,247],{"class":35,"line":246},22,[33,248,249],{"class":64},"\u002F\u002F ── UNCONTROLLED: the DOM owns the value ──\n",[33,251,253],{"class":35,"line":252},23,[33,254,255],{"class":64},"\u002F\u002F defaultValue={initial} (set once on mount) + ref to read the value when needed.\n",[33,257,259],{"class":35,"line":258},24,[33,260,261],{"class":64},"\u002F\u002F React does NOT control the value — the browser manages it as users type.\n",[33,263,265],{"class":35,"line":264},25,[33,266,58],{"emptyLinePlaceholder":57},[33,268,270,272,275],{"class":35,"line":269},26,[33,271,111],{"class":39},[33,273,274],{"class":114}," UncontrolledInput",[33,276,118],{"class":43},[33,278,280,282,285,288,291,293,296],{"class":35,"line":279},27,[33,281,124],{"class":39},[33,283,284],{"class":130}," inputRef",[33,286,287],{"class":39}," =",[33,289,290],{"class":114}," useRef",[33,292,149],{"class":43},[33,294,295],{"class":130},"null",[33,297,155],{"class":43},[33,299,301],{"class":35,"line":300},28,[33,302,58],{"emptyLinePlaceholder":57},[33,304,306,309,312,314,316],{"class":35,"line":305},29,[33,307,308],{"class":39},"  function",[33,310,311],{"class":114}," handleSubmit",[33,313,149],{"class":43},[33,315,211],{"class":210},[33,317,318],{"class":43},") {\n",[33,320,322,325,328],{"class":35,"line":321},30,[33,323,324],{"class":43},"    e.",[33,326,327],{"class":114},"preventDefault",[33,329,330],{"class":43},"()\n",[33,332,334,337,340],{"class":35,"line":333},31,[33,335,336],{"class":43},"    console.",[33,338,339],{"class":114},"log",[33,341,342],{"class":43},"(inputRef.current.value)\n",[33,344,346],{"class":35,"line":345},32,[33,347,348],{"class":43},"  }\n",[33,350,352],{"class":35,"line":351},33,[33,353,58],{"emptyLinePlaceholder":57},[33,355,357,359],{"class":35,"line":356},34,[33,358,161],{"class":39},[33,360,164],{"class":43},[33,362,364,366,369,372,374],{"class":35,"line":363},35,[33,365,170],{"class":43},[33,367,368],{"class":173},"form",[33,370,371],{"class":114}," onSubmit",[33,373,143],{"class":39},[33,375,376],{"class":43},"{handleSubmit}>\n",[33,378,380,383,386,389,391,394,397,399,402,405,407],{"class":35,"line":379},36,[33,381,382],{"class":43},"      \u003C",[33,384,385],{"class":173},"input",[33,387,388],{"class":114}," type",[33,390,143],{"class":39},[33,392,393],{"class":50},"\"text\"",[33,395,396],{"class":114}," defaultValue",[33,398,143],{"class":39},[33,400,401],{"class":50},"\"\"",[33,403,404],{"class":114}," ref",[33,406,143],{"class":39},[33,408,409],{"class":43},"{inputRef} \u002F>\n",[33,411,413,415,418,420,422,425,428,430],{"class":35,"line":412},37,[33,414,382],{"class":43},[33,416,417],{"class":173},"button",[33,419,388],{"class":114},[33,421,143],{"class":39},[33,423,424],{"class":50},"\"submit\"",[33,426,427],{"class":43},">Submit\u003C\u002F",[33,429,417],{"class":173},[33,431,432],{"class":43},">\n",[33,434,436,439,441],{"class":35,"line":435},38,[33,437,438],{"class":43},"    \u003C\u002F",[33,440,368],{"class":173},[33,442,432],{"class":43},[33,444,446],{"class":35,"line":445},39,[33,447,232],{"class":43},[33,449,451],{"class":35,"line":450},40,[33,452,238],{"class":43},[14,454,456],{"id":455},"the-controlled-input-loop","The Controlled Input Loop",[19,458,460],{"filename":459,"language":22},"controlled_loop.js",[24,461,463],{"className":26,"code":462,"language":22,"meta":28,"style":28},"import { useState } from 'react'\n\n\u002F\u002F The one-way data flow of a controlled input:\n\u002F\u002F   User types 'h' → DOM input event → onChange: setEmail('h') → state = 'h'\n\u002F\u002F   → component re-renders → \u003Cinput value=\"h\" \u002F> → React updates DOM → DOM displays 'h'\n\u002F\u002F This loop ensures the DOM value and React state can NEVER diverge.\n\u002F\u002F The cost: a re-render on every keystroke. For most forms, negligible.\n\n\u002F\u002F ANTI-PATTERN: value without onChange — silently rejects all typing\nfunction BrokenReadOnlyInput() {\n  const [name] = useState('')\n  return \u003Cinput value={name} \u002F>\n  \u002F\u002F Every keystroke: React re-renders, value is still '' → DOM reset to ''.\n  \u002F\u002F The user's typed character is immediately overwritten. Looks read-only.\n}\n\n\u002F\u002F ANTI-PATTERN: value={undefined} on first render → controlled\u002Funcontrolled warning\nfunction FlakyInput({ initialValue }) {\n  const [value, setValue] = useState(initialValue)  \u002F\u002F undefined if not passed\n  return \u003Cinput value={value} onChange={e => setValue(e.target.value)} \u002F>\n  \u002F\u002F First render: value={undefined} → uncontrolled. After keystroke: controlled.\n  \u002F\u002F React warns: \"changing an uncontrolled input to be controlled.\"\n}\n\n\u002F\u002F CORRECT: always initialize to a properly-typed empty value\nfunction SafeInput({ initialValue }) {\n  const [value, setValue] = useState(initialValue ?? '')\n  return \u003Cinput value={value} onChange={e => setValue(e.target.value)} \u002F>\n}\n",[30,464,465,476,480,485,490,495,500,505,509,514,523,544,561,566,571,575,579,584,600,626,658,663,668,672,676,681,694,723,751],{"__ignoreMap":28},[33,466,467,469,472,474],{"class":35,"line":36},[33,468,40],{"class":39},[33,470,471],{"class":43}," { useState } ",[33,473,47],{"class":39},[33,475,51],{"class":50},[33,477,478],{"class":35,"line":54},[33,479,58],{"emptyLinePlaceholder":57},[33,481,482],{"class":35,"line":61},[33,483,484],{"class":64},"\u002F\u002F The one-way data flow of a controlled input:\n",[33,486,487],{"class":35,"line":68},[33,488,489],{"class":64},"\u002F\u002F   User types 'h' → DOM input event → onChange: setEmail('h') → state = 'h'\n",[33,491,492],{"class":35,"line":74},[33,493,494],{"class":64},"\u002F\u002F   → component re-renders → \u003Cinput value=\"h\" \u002F> → React updates DOM → DOM displays 'h'\n",[33,496,497],{"class":35,"line":79},[33,498,499],{"class":64},"\u002F\u002F This loop ensures the DOM value and React state can NEVER diverge.\n",[33,501,502],{"class":35,"line":85},[33,503,504],{"class":64},"\u002F\u002F The cost: a re-render on every keystroke. For most forms, negligible.\n",[33,506,507],{"class":35,"line":91},[33,508,58],{"emptyLinePlaceholder":57},[33,510,511],{"class":35,"line":97},[33,512,513],{"class":64},"\u002F\u002F ANTI-PATTERN: value without onChange — silently rejects all typing\n",[33,515,516,518,521],{"class":35,"line":103},[33,517,111],{"class":39},[33,519,520],{"class":114}," BrokenReadOnlyInput",[33,522,118],{"class":43},[33,524,525,527,529,532,534,536,538,540,542],{"class":35,"line":108},[33,526,124],{"class":39},[33,528,127],{"class":43},[33,530,531],{"class":130},"name",[33,533,140],{"class":43},[33,535,143],{"class":39},[33,537,146],{"class":114},[33,539,149],{"class":43},[33,541,152],{"class":50},[33,543,155],{"class":43},[33,545,546,548,551,553,556,558],{"class":35,"line":121},[33,547,161],{"class":39},[33,549,550],{"class":43}," \u003C",[33,552,385],{"class":173},[33,554,555],{"class":114}," value",[33,557,143],{"class":39},[33,559,560],{"class":43},"{name} \u002F>\n",[33,562,563],{"class":35,"line":158},[33,564,565],{"class":64},"  \u002F\u002F Every keystroke: React re-renders, value is still '' → DOM reset to ''.\n",[33,567,568],{"class":35,"line":167},[33,569,570],{"class":64},"  \u002F\u002F The user's typed character is immediately overwritten. Looks read-only.\n",[33,572,573],{"class":35,"line":177},[33,574,238],{"class":43},[33,576,577],{"class":35,"line":188},[33,578,58],{"emptyLinePlaceholder":57},[33,580,581],{"class":35,"line":199},[33,582,583],{"class":64},"\u002F\u002F ANTI-PATTERN: value={undefined} on first render → controlled\u002Funcontrolled warning\n",[33,585,586,588,591,594,597],{"class":35,"line":223},[33,587,111],{"class":39},[33,589,590],{"class":114}," FlakyInput",[33,592,593],{"class":43},"({ ",[33,595,596],{"class":210},"initialValue",[33,598,599],{"class":43}," }) {\n",[33,601,602,604,606,609,611,614,616,618,620,623],{"class":35,"line":229},[33,603,124],{"class":39},[33,605,127],{"class":43},[33,607,608],{"class":130},"value",[33,610,134],{"class":43},[33,612,613],{"class":130},"setValue",[33,615,140],{"class":43},[33,617,143],{"class":39},[33,619,146],{"class":114},[33,621,622],{"class":43},"(initialValue)  ",[33,624,625],{"class":64},"\u002F\u002F undefined if not passed\n",[33,627,628,630,632,634,636,638,641,644,646,648,650,652,655],{"class":35,"line":235},[33,629,161],{"class":39},[33,631,550],{"class":43},[33,633,385],{"class":173},[33,635,555],{"class":114},[33,637,143],{"class":39},[33,639,640],{"class":43},"{value} ",[33,642,643],{"class":114},"onChange",[33,645,143],{"class":39},[33,647,207],{"class":43},[33,649,211],{"class":210},[33,651,214],{"class":39},[33,653,654],{"class":114}," setValue",[33,656,657],{"class":43},"(e.target.value)} \u002F>\n",[33,659,660],{"class":35,"line":241},[33,661,662],{"class":64},"  \u002F\u002F First render: value={undefined} → uncontrolled. After keystroke: controlled.\n",[33,664,665],{"class":35,"line":246},[33,666,667],{"class":64},"  \u002F\u002F React warns: \"changing an uncontrolled input to be controlled.\"\n",[33,669,670],{"class":35,"line":252},[33,671,238],{"class":43},[33,673,674],{"class":35,"line":258},[33,675,58],{"emptyLinePlaceholder":57},[33,677,678],{"class":35,"line":264},[33,679,680],{"class":64},"\u002F\u002F CORRECT: always initialize to a properly-typed empty value\n",[33,682,683,685,688,690,692],{"class":35,"line":269},[33,684,111],{"class":39},[33,686,687],{"class":114}," SafeInput",[33,689,593],{"class":43},[33,691,596],{"class":210},[33,693,599],{"class":43},[33,695,696,698,700,702,704,706,708,710,712,715,718,721],{"class":35,"line":279},[33,697,124],{"class":39},[33,699,127],{"class":43},[33,701,608],{"class":130},[33,703,134],{"class":43},[33,705,613],{"class":130},[33,707,140],{"class":43},[33,709,143],{"class":39},[33,711,146],{"class":114},[33,713,714],{"class":43},"(initialValue ",[33,716,717],{"class":39},"??",[33,719,720],{"class":50}," ''",[33,722,155],{"class":43},[33,724,725,727,729,731,733,735,737,739,741,743,745,747,749],{"class":35,"line":300},[33,726,161],{"class":39},[33,728,550],{"class":43},[33,730,385],{"class":173},[33,732,555],{"class":114},[33,734,143],{"class":39},[33,736,640],{"class":43},[33,738,643],{"class":114},[33,740,143],{"class":39},[33,742,207],{"class":43},[33,744,211],{"class":210},[33,746,214],{"class":39},[33,748,654],{"class":114},[33,750,657],{"class":43},[33,752,753],{"class":35,"line":305},[33,754,238],{"class":43},[14,756,758],{"id":757},"controlled-input-with-live-transformation","Controlled Input with Live Transformation",[19,760,762],{"filename":761,"language":22},"live_transformation.js",[24,763,765],{"className":26,"code":764,"language":22,"meta":28,"style":28},"import { useState } from 'react'\n\n\u002F\u002F The power of controlled inputs: transform\u002Ffilter\u002Fformat on every keystroke\n\u002F\u002F because the value flows through your state on every change.\n\nfunction PhoneInput() {\n  const [digits, setDigits] = useState('')\n\n  function handleChange(e) {\n    const onlyDigits = e.target.value.replace(\u002F\\D\u002Fg, '').slice(0, 10)\n    setDigits(onlyDigits)\n  }\n\n  const formatted = digits.replace(\u002F(\\d{3})(\\d{0,3})(\\d{0,4})\u002F, (_, a, b, c) =>\n    [a, b, c].filter(Boolean).join('-')\n  )\n\n  return (\n    \u003Cinput\n      type=\"tel\"\n      value={formatted}\n      onChange={handleChange}\n      placeholder=\"555-123-4567\"\n    \u002F>\n  )\n  \u002F\u002F User types \"5551234567\" → sees \"555-123-4567\" → state stores \"5551234567\"\n}\n\nfunction UpperCaseInput() {\n  const [value, setValue] = useState('')\n  return (\n    \u003Cinput\n      value={value}\n      onChange={e => setValue(e.target.value.toUpperCase())}\n      placeholder=\"AUTO-UPPERCASE\"\n    \u002F>\n  )\n}\n\nfunction AgeInput() {\n  const [age, setAge] = useState('')\n  function handleChange(e) {\n    const raw = e.target.value.replace(\u002F\\D\u002Fg, '')\n    const num = raw === '' ? '' : Math.min(150, Math.max(0, parseInt(raw, 10)))\n    setAge(num)\n  }\n  return \u003Cinput type=\"number\" value={age} onChange={handleChange} min={0} max={150} \u002F>\n}\n",[30,766,767,777,781,786,791,795,804,830,834,847,898,906,910,914,988,1009,1013,1017,1023,1029,1038,1047,1056,1066,1070,1074,1079,1083,1087,1096,1120,1126,1132,1141,1164,1173,1177,1181,1185,1189,1198,1225,1238,1268,1328,1337,1342,1394],{"__ignoreMap":28},[33,768,769,771,773,775],{"class":35,"line":36},[33,770,40],{"class":39},[33,772,471],{"class":43},[33,774,47],{"class":39},[33,776,51],{"class":50},[33,778,779],{"class":35,"line":54},[33,780,58],{"emptyLinePlaceholder":57},[33,782,783],{"class":35,"line":61},[33,784,785],{"class":64},"\u002F\u002F The power of controlled inputs: transform\u002Ffilter\u002Fformat on every keystroke\n",[33,787,788],{"class":35,"line":68},[33,789,790],{"class":64},"\u002F\u002F because the value flows through your state on every change.\n",[33,792,793],{"class":35,"line":74},[33,794,58],{"emptyLinePlaceholder":57},[33,796,797,799,802],{"class":35,"line":79},[33,798,111],{"class":39},[33,800,801],{"class":114}," PhoneInput",[33,803,118],{"class":43},[33,805,806,808,810,813,815,818,820,822,824,826,828],{"class":35,"line":85},[33,807,124],{"class":39},[33,809,127],{"class":43},[33,811,812],{"class":130},"digits",[33,814,134],{"class":43},[33,816,817],{"class":130},"setDigits",[33,819,140],{"class":43},[33,821,143],{"class":39},[33,823,146],{"class":114},[33,825,149],{"class":43},[33,827,152],{"class":50},[33,829,155],{"class":43},[33,831,832],{"class":35,"line":91},[33,833,58],{"emptyLinePlaceholder":57},[33,835,836,838,841,843,845],{"class":35,"line":97},[33,837,308],{"class":39},[33,839,840],{"class":114}," handleChange",[33,842,149],{"class":43},[33,844,211],{"class":210},[33,846,318],{"class":43},[33,848,849,852,855,857,860,863,865,868,871,873,876,878,880,883,886,888,891,893,896],{"class":35,"line":103},[33,850,851],{"class":39},"    const",[33,853,854],{"class":130}," onlyDigits",[33,856,287],{"class":39},[33,858,859],{"class":43}," e.target.value.",[33,861,862],{"class":114},"replace",[33,864,149],{"class":43},[33,866,867],{"class":50},"\u002F",[33,869,870],{"class":130},"\\D",[33,872,867],{"class":50},[33,874,875],{"class":39},"g",[33,877,134],{"class":43},[33,879,152],{"class":50},[33,881,882],{"class":43},").",[33,884,885],{"class":114},"slice",[33,887,149],{"class":43},[33,889,890],{"class":130},"0",[33,892,134],{"class":43},[33,894,895],{"class":130},"10",[33,897,155],{"class":43},[33,899,900,903],{"class":35,"line":108},[33,901,902],{"class":114},"    setDigits",[33,904,905],{"class":43},"(onlyDigits)\n",[33,907,908],{"class":35,"line":121},[33,909,348],{"class":43},[33,911,912],{"class":35,"line":158},[33,913,58],{"emptyLinePlaceholder":57},[33,915,916,918,921,923,926,928,930,932,935,938,941,944,946,949,951,953,956,959,961,964,967,969,972,974,977,979,982,985],{"class":35,"line":167},[33,917,124],{"class":39},[33,919,920],{"class":130}," formatted",[33,922,287],{"class":39},[33,924,925],{"class":43}," digits.",[33,927,862],{"class":114},[33,929,149],{"class":43},[33,931,867],{"class":50},[33,933,149],{"class":934},"svAP2",[33,936,937],{"class":130},"\\d",[33,939,940],{"class":39},"{3}",[33,942,943],{"class":934},")(",[33,945,937],{"class":130},[33,947,948],{"class":39},"{0,3}",[33,950,943],{"class":934},[33,952,937],{"class":130},[33,954,955],{"class":39},"{0,4}",[33,957,958],{"class":934},")",[33,960,867],{"class":50},[33,962,963],{"class":43},", (",[33,965,966],{"class":210},"_",[33,968,134],{"class":43},[33,970,971],{"class":210},"a",[33,973,134],{"class":43},[33,975,976],{"class":210},"b",[33,978,134],{"class":43},[33,980,981],{"class":210},"c",[33,983,984],{"class":43},") ",[33,986,987],{"class":39},"=>\n",[33,989,990,993,996,999,1002,1004,1007],{"class":35,"line":177},[33,991,992],{"class":43},"    [a, b, c].",[33,994,995],{"class":114},"filter",[33,997,998],{"class":43},"(Boolean).",[33,1000,1001],{"class":114},"join",[33,1003,149],{"class":43},[33,1005,1006],{"class":50},"'-'",[33,1008,155],{"class":43},[33,1010,1011],{"class":35,"line":188},[33,1012,232],{"class":43},[33,1014,1015],{"class":35,"line":199},[33,1016,58],{"emptyLinePlaceholder":57},[33,1018,1019,1021],{"class":35,"line":223},[33,1020,161],{"class":39},[33,1022,164],{"class":43},[33,1024,1025,1027],{"class":35,"line":229},[33,1026,170],{"class":43},[33,1028,174],{"class":173},[33,1030,1031,1033,1035],{"class":35,"line":235},[33,1032,180],{"class":114},[33,1034,143],{"class":39},[33,1036,1037],{"class":50},"\"tel\"\n",[33,1039,1040,1042,1044],{"class":35,"line":241},[33,1041,191],{"class":114},[33,1043,143],{"class":39},[33,1045,1046],{"class":43},"{formatted}\n",[33,1048,1049,1051,1053],{"class":35,"line":246},[33,1050,202],{"class":114},[33,1052,143],{"class":39},[33,1054,1055],{"class":43},"{handleChange}\n",[33,1057,1058,1061,1063],{"class":35,"line":252},[33,1059,1060],{"class":114},"      placeholder",[33,1062,143],{"class":39},[33,1064,1065],{"class":50},"\"555-123-4567\"\n",[33,1067,1068],{"class":35,"line":258},[33,1069,226],{"class":43},[33,1071,1072],{"class":35,"line":264},[33,1073,232],{"class":43},[33,1075,1076],{"class":35,"line":269},[33,1077,1078],{"class":64},"  \u002F\u002F User types \"5551234567\" → sees \"555-123-4567\" → state stores \"5551234567\"\n",[33,1080,1081],{"class":35,"line":279},[33,1082,238],{"class":43},[33,1084,1085],{"class":35,"line":300},[33,1086,58],{"emptyLinePlaceholder":57},[33,1088,1089,1091,1094],{"class":35,"line":305},[33,1090,111],{"class":39},[33,1092,1093],{"class":114}," UpperCaseInput",[33,1095,118],{"class":43},[33,1097,1098,1100,1102,1104,1106,1108,1110,1112,1114,1116,1118],{"class":35,"line":321},[33,1099,124],{"class":39},[33,1101,127],{"class":43},[33,1103,608],{"class":130},[33,1105,134],{"class":43},[33,1107,613],{"class":130},[33,1109,140],{"class":43},[33,1111,143],{"class":39},[33,1113,146],{"class":114},[33,1115,149],{"class":43},[33,1117,152],{"class":50},[33,1119,155],{"class":43},[33,1121,1122,1124],{"class":35,"line":333},[33,1123,161],{"class":39},[33,1125,164],{"class":43},[33,1127,1128,1130],{"class":35,"line":345},[33,1129,170],{"class":43},[33,1131,174],{"class":173},[33,1133,1134,1136,1138],{"class":35,"line":351},[33,1135,191],{"class":114},[33,1137,143],{"class":39},[33,1139,1140],{"class":43},"{value}\n",[33,1142,1143,1145,1147,1149,1151,1153,1155,1158,1161],{"class":35,"line":356},[33,1144,202],{"class":114},[33,1146,143],{"class":39},[33,1148,207],{"class":43},[33,1150,211],{"class":210},[33,1152,214],{"class":39},[33,1154,654],{"class":114},[33,1156,1157],{"class":43},"(e.target.value.",[33,1159,1160],{"class":114},"toUpperCase",[33,1162,1163],{"class":43},"())}\n",[33,1165,1166,1168,1170],{"class":35,"line":363},[33,1167,1060],{"class":114},[33,1169,143],{"class":39},[33,1171,1172],{"class":50},"\"AUTO-UPPERCASE\"\n",[33,1174,1175],{"class":35,"line":379},[33,1176,226],{"class":43},[33,1178,1179],{"class":35,"line":412},[33,1180,232],{"class":43},[33,1182,1183],{"class":35,"line":435},[33,1184,238],{"class":43},[33,1186,1187],{"class":35,"line":445},[33,1188,58],{"emptyLinePlaceholder":57},[33,1190,1191,1193,1196],{"class":35,"line":450},[33,1192,111],{"class":39},[33,1194,1195],{"class":114}," AgeInput",[33,1197,118],{"class":43},[33,1199,1201,1203,1205,1208,1210,1213,1215,1217,1219,1221,1223],{"class":35,"line":1200},41,[33,1202,124],{"class":39},[33,1204,127],{"class":43},[33,1206,1207],{"class":130},"age",[33,1209,134],{"class":43},[33,1211,1212],{"class":130},"setAge",[33,1214,140],{"class":43},[33,1216,143],{"class":39},[33,1218,146],{"class":114},[33,1220,149],{"class":43},[33,1222,152],{"class":50},[33,1224,155],{"class":43},[33,1226,1228,1230,1232,1234,1236],{"class":35,"line":1227},42,[33,1229,308],{"class":39},[33,1231,840],{"class":114},[33,1233,149],{"class":43},[33,1235,211],{"class":210},[33,1237,318],{"class":43},[33,1239,1241,1243,1246,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266],{"class":35,"line":1240},43,[33,1242,851],{"class":39},[33,1244,1245],{"class":130}," raw",[33,1247,287],{"class":39},[33,1249,859],{"class":43},[33,1251,862],{"class":114},[33,1253,149],{"class":43},[33,1255,867],{"class":50},[33,1257,870],{"class":130},[33,1259,867],{"class":50},[33,1261,875],{"class":39},[33,1263,134],{"class":43},[33,1265,152],{"class":50},[33,1267,155],{"class":43},[33,1269,1271,1273,1276,1278,1281,1284,1286,1289,1291,1294,1297,1300,1302,1305,1308,1311,1313,1315,1317,1320,1323,1325],{"class":35,"line":1270},44,[33,1272,851],{"class":39},[33,1274,1275],{"class":130}," num",[33,1277,287],{"class":39},[33,1279,1280],{"class":43}," raw ",[33,1282,1283],{"class":39},"===",[33,1285,720],{"class":50},[33,1287,1288],{"class":39}," ?",[33,1290,720],{"class":50},[33,1292,1293],{"class":39}," :",[33,1295,1296],{"class":43}," Math.",[33,1298,1299],{"class":114},"min",[33,1301,149],{"class":43},[33,1303,1304],{"class":130},"150",[33,1306,1307],{"class":43},", Math.",[33,1309,1310],{"class":114},"max",[33,1312,149],{"class":43},[33,1314,890],{"class":130},[33,1316,134],{"class":43},[33,1318,1319],{"class":114},"parseInt",[33,1321,1322],{"class":43},"(raw, ",[33,1324,895],{"class":130},[33,1326,1327],{"class":43},")))\n",[33,1329,1331,1334],{"class":35,"line":1330},45,[33,1332,1333],{"class":114},"    setAge",[33,1335,1336],{"class":43},"(num)\n",[33,1338,1340],{"class":35,"line":1339},46,[33,1341,348],{"class":43},[33,1343,1345,1347,1349,1351,1353,1355,1358,1360,1362,1365,1367,1369,1372,1374,1376,1378,1380,1383,1385,1387,1389,1391],{"class":35,"line":1344},47,[33,1346,161],{"class":39},[33,1348,550],{"class":43},[33,1350,385],{"class":173},[33,1352,388],{"class":114},[33,1354,143],{"class":39},[33,1356,1357],{"class":50},"\"number\"",[33,1359,555],{"class":114},[33,1361,143],{"class":39},[33,1363,1364],{"class":43},"{age} ",[33,1366,643],{"class":114},[33,1368,143],{"class":39},[33,1370,1371],{"class":43},"{handleChange} ",[33,1373,1299],{"class":114},[33,1375,143],{"class":39},[33,1377,207],{"class":43},[33,1379,890],{"class":130},[33,1381,1382],{"class":43},"} ",[33,1384,1310],{"class":114},[33,1386,143],{"class":39},[33,1388,207],{"class":43},[33,1390,1304],{"class":130},[33,1392,1393],{"class":43},"} \u002F>\n",[33,1395,1397],{"class":35,"line":1396},48,[33,1398,238],{"class":43},[14,1400,1402],{"id":1401},"uncontrolled-inputs-with-useref","Uncontrolled Inputs with useRef",[19,1404,1406],{"filename":1405,"language":22},"uncontrolled_useRef.js",[24,1407,1409],{"className":26,"code":1408,"language":22,"meta":28,"style":28},"import { useRef } from 'react'\n\n\u002F\u002F Uncontrolled inputs are simpler for forms that only need the value at submit time.\n\u002F\u002F No re-render on every keystroke — the DOM manages its own value.\n\nfunction SimpleContactForm() {\n  const nameRef = useRef(null)\n  const emailRef = useRef(null)\n  const messageRef = useRef(null)\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    const data = {\n      name: nameRef.current.value,\n      email: emailRef.current.value,\n      message: messageRef.current.value,\n    }\n    submitContactForm(data)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput type=\"text\" name=\"name\" defaultValue=\"\" ref={nameRef} required \u002F>\n      \u003Cinput type=\"email\" name=\"email\" defaultValue=\"\" ref={emailRef} required \u002F>\n      \u003Ctextarea name=\"message\" defaultValue=\"\" ref={messageRef} required \u002F>\n      \u003Cbutton type=\"submit\">Send\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n  \u002F\u002F Pros: no per-keystroke re-renders, less code for simple forms.\n  \u002F\u002F Cons: can't validate\u002Fformat\u002Freact to the value live.\n}\n\nfunction ResettableForm() {\n  const formRef = useRef(null)\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    const formData = new FormData(e.target)\n    submitData(Object.fromEntries(formData))\n    e.target.reset()\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit} ref={formRef}>\n      \u003Cinput name=\"username\" defaultValue=\"\" \u002F>\n      \u003Cinput name=\"bio\" defaultValue=\"\" \u002F>\n      \u003Cbutton type=\"submit\">Submit\u003C\u002Fbutton>\n      \u003Cbutton type=\"button\" onClick={() => formRef.current.reset()}>Reset\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n",[30,1410,1411,1422,1426,1431,1436,1440,1449,1466,1483,1500,1504,1516,1524,1536,1541,1546,1551,1556,1564,1568,1572,1578,1590,1629,1665,1696,1715,1723,1727,1732,1737,1741,1745,1754,1771,1775,1787,1795,1813,1827,1837,1841,1845,1851,1872,1893,1914,1932,1968,1977,1982],{"__ignoreMap":28},[33,1412,1413,1415,1418,1420],{"class":35,"line":36},[33,1414,40],{"class":39},[33,1416,1417],{"class":43}," { useRef } ",[33,1419,47],{"class":39},[33,1421,51],{"class":50},[33,1423,1424],{"class":35,"line":54},[33,1425,58],{"emptyLinePlaceholder":57},[33,1427,1428],{"class":35,"line":61},[33,1429,1430],{"class":64},"\u002F\u002F Uncontrolled inputs are simpler for forms that only need the value at submit time.\n",[33,1432,1433],{"class":35,"line":68},[33,1434,1435],{"class":64},"\u002F\u002F No re-render on every keystroke — the DOM manages its own value.\n",[33,1437,1438],{"class":35,"line":74},[33,1439,58],{"emptyLinePlaceholder":57},[33,1441,1442,1444,1447],{"class":35,"line":79},[33,1443,111],{"class":39},[33,1445,1446],{"class":114}," SimpleContactForm",[33,1448,118],{"class":43},[33,1450,1451,1453,1456,1458,1460,1462,1464],{"class":35,"line":85},[33,1452,124],{"class":39},[33,1454,1455],{"class":130}," nameRef",[33,1457,287],{"class":39},[33,1459,290],{"class":114},[33,1461,149],{"class":43},[33,1463,295],{"class":130},[33,1465,155],{"class":43},[33,1467,1468,1470,1473,1475,1477,1479,1481],{"class":35,"line":91},[33,1469,124],{"class":39},[33,1471,1472],{"class":130}," emailRef",[33,1474,287],{"class":39},[33,1476,290],{"class":114},[33,1478,149],{"class":43},[33,1480,295],{"class":130},[33,1482,155],{"class":43},[33,1484,1485,1487,1490,1492,1494,1496,1498],{"class":35,"line":97},[33,1486,124],{"class":39},[33,1488,1489],{"class":130}," messageRef",[33,1491,287],{"class":39},[33,1493,290],{"class":114},[33,1495,149],{"class":43},[33,1497,295],{"class":130},[33,1499,155],{"class":43},[33,1501,1502],{"class":35,"line":103},[33,1503,58],{"emptyLinePlaceholder":57},[33,1505,1506,1508,1510,1512,1514],{"class":35,"line":108},[33,1507,308],{"class":39},[33,1509,311],{"class":114},[33,1511,149],{"class":43},[33,1513,211],{"class":210},[33,1515,318],{"class":43},[33,1517,1518,1520,1522],{"class":35,"line":121},[33,1519,324],{"class":43},[33,1521,327],{"class":114},[33,1523,330],{"class":43},[33,1525,1526,1528,1531,1533],{"class":35,"line":158},[33,1527,851],{"class":39},[33,1529,1530],{"class":130}," data",[33,1532,287],{"class":39},[33,1534,1535],{"class":43}," {\n",[33,1537,1538],{"class":35,"line":167},[33,1539,1540],{"class":43},"      name: nameRef.current.value,\n",[33,1542,1543],{"class":35,"line":177},[33,1544,1545],{"class":43},"      email: emailRef.current.value,\n",[33,1547,1548],{"class":35,"line":188},[33,1549,1550],{"class":43},"      message: messageRef.current.value,\n",[33,1552,1553],{"class":35,"line":199},[33,1554,1555],{"class":43},"    }\n",[33,1557,1558,1561],{"class":35,"line":223},[33,1559,1560],{"class":114},"    submitContactForm",[33,1562,1563],{"class":43},"(data)\n",[33,1565,1566],{"class":35,"line":229},[33,1567,348],{"class":43},[33,1569,1570],{"class":35,"line":235},[33,1571,58],{"emptyLinePlaceholder":57},[33,1573,1574,1576],{"class":35,"line":241},[33,1575,161],{"class":39},[33,1577,164],{"class":43},[33,1579,1580,1582,1584,1586,1588],{"class":35,"line":246},[33,1581,170],{"class":43},[33,1583,368],{"class":173},[33,1585,371],{"class":114},[33,1587,143],{"class":39},[33,1589,376],{"class":43},[33,1591,1592,1594,1596,1598,1600,1602,1605,1607,1610,1612,1614,1616,1618,1620,1623,1626],{"class":35,"line":252},[33,1593,382],{"class":43},[33,1595,385],{"class":173},[33,1597,388],{"class":114},[33,1599,143],{"class":39},[33,1601,393],{"class":50},[33,1603,1604],{"class":114}," name",[33,1606,143],{"class":39},[33,1608,1609],{"class":50},"\"name\"",[33,1611,396],{"class":114},[33,1613,143],{"class":39},[33,1615,401],{"class":50},[33,1617,404],{"class":114},[33,1619,143],{"class":39},[33,1621,1622],{"class":43},"{nameRef} ",[33,1624,1625],{"class":114},"required",[33,1627,1628],{"class":43}," \u002F>\n",[33,1630,1631,1633,1635,1637,1639,1642,1644,1646,1648,1650,1652,1654,1656,1658,1661,1663],{"class":35,"line":258},[33,1632,382],{"class":43},[33,1634,385],{"class":173},[33,1636,388],{"class":114},[33,1638,143],{"class":39},[33,1640,1641],{"class":50},"\"email\"",[33,1643,1604],{"class":114},[33,1645,143],{"class":39},[33,1647,1641],{"class":50},[33,1649,396],{"class":114},[33,1651,143],{"class":39},[33,1653,401],{"class":50},[33,1655,404],{"class":114},[33,1657,143],{"class":39},[33,1659,1660],{"class":43},"{emailRef} ",[33,1662,1625],{"class":114},[33,1664,1628],{"class":43},[33,1666,1667,1669,1672,1674,1676,1679,1681,1683,1685,1687,1689,1692,1694],{"class":35,"line":264},[33,1668,382],{"class":43},[33,1670,1671],{"class":173},"textarea",[33,1673,1604],{"class":114},[33,1675,143],{"class":39},[33,1677,1678],{"class":50},"\"message\"",[33,1680,396],{"class":114},[33,1682,143],{"class":39},[33,1684,401],{"class":50},[33,1686,404],{"class":114},[33,1688,143],{"class":39},[33,1690,1691],{"class":43},"{messageRef} ",[33,1693,1625],{"class":114},[33,1695,1628],{"class":43},[33,1697,1698,1700,1702,1704,1706,1708,1711,1713],{"class":35,"line":269},[33,1699,382],{"class":43},[33,1701,417],{"class":173},[33,1703,388],{"class":114},[33,1705,143],{"class":39},[33,1707,424],{"class":50},[33,1709,1710],{"class":43},">Send\u003C\u002F",[33,1712,417],{"class":173},[33,1714,432],{"class":43},[33,1716,1717,1719,1721],{"class":35,"line":279},[33,1718,438],{"class":43},[33,1720,368],{"class":173},[33,1722,432],{"class":43},[33,1724,1725],{"class":35,"line":300},[33,1726,232],{"class":43},[33,1728,1729],{"class":35,"line":305},[33,1730,1731],{"class":64},"  \u002F\u002F Pros: no per-keystroke re-renders, less code for simple forms.\n",[33,1733,1734],{"class":35,"line":321},[33,1735,1736],{"class":64},"  \u002F\u002F Cons: can't validate\u002Fformat\u002Freact to the value live.\n",[33,1738,1739],{"class":35,"line":333},[33,1740,238],{"class":43},[33,1742,1743],{"class":35,"line":345},[33,1744,58],{"emptyLinePlaceholder":57},[33,1746,1747,1749,1752],{"class":35,"line":351},[33,1748,111],{"class":39},[33,1750,1751],{"class":114}," ResettableForm",[33,1753,118],{"class":43},[33,1755,1756,1758,1761,1763,1765,1767,1769],{"class":35,"line":356},[33,1757,124],{"class":39},[33,1759,1760],{"class":130}," formRef",[33,1762,287],{"class":39},[33,1764,290],{"class":114},[33,1766,149],{"class":43},[33,1768,295],{"class":130},[33,1770,155],{"class":43},[33,1772,1773],{"class":35,"line":363},[33,1774,58],{"emptyLinePlaceholder":57},[33,1776,1777,1779,1781,1783,1785],{"class":35,"line":379},[33,1778,308],{"class":39},[33,1780,311],{"class":114},[33,1782,149],{"class":43},[33,1784,211],{"class":210},[33,1786,318],{"class":43},[33,1788,1789,1791,1793],{"class":35,"line":412},[33,1790,324],{"class":43},[33,1792,327],{"class":114},[33,1794,330],{"class":43},[33,1796,1797,1799,1802,1804,1807,1810],{"class":35,"line":435},[33,1798,851],{"class":39},[33,1800,1801],{"class":130}," formData",[33,1803,287],{"class":39},[33,1805,1806],{"class":39}," new",[33,1808,1809],{"class":114}," FormData",[33,1811,1812],{"class":43},"(e.target)\n",[33,1814,1815,1818,1821,1824],{"class":35,"line":445},[33,1816,1817],{"class":114},"    submitData",[33,1819,1820],{"class":43},"(Object.",[33,1822,1823],{"class":114},"fromEntries",[33,1825,1826],{"class":43},"(formData))\n",[33,1828,1829,1832,1835],{"class":35,"line":450},[33,1830,1831],{"class":43},"    e.target.",[33,1833,1834],{"class":114},"reset",[33,1836,330],{"class":43},[33,1838,1839],{"class":35,"line":1200},[33,1840,348],{"class":43},[33,1842,1843],{"class":35,"line":1227},[33,1844,58],{"emptyLinePlaceholder":57},[33,1846,1847,1849],{"class":35,"line":1240},[33,1848,161],{"class":39},[33,1850,164],{"class":43},[33,1852,1853,1855,1857,1859,1861,1864,1867,1869],{"class":35,"line":1270},[33,1854,170],{"class":43},[33,1856,368],{"class":173},[33,1858,371],{"class":114},[33,1860,143],{"class":39},[33,1862,1863],{"class":43},"{handleSubmit} ",[33,1865,1866],{"class":114},"ref",[33,1868,143],{"class":39},[33,1870,1871],{"class":43},"{formRef}>\n",[33,1873,1874,1876,1878,1880,1882,1885,1887,1889,1891],{"class":35,"line":1330},[33,1875,382],{"class":43},[33,1877,385],{"class":173},[33,1879,1604],{"class":114},[33,1881,143],{"class":39},[33,1883,1884],{"class":50},"\"username\"",[33,1886,396],{"class":114},[33,1888,143],{"class":39},[33,1890,401],{"class":50},[33,1892,1628],{"class":43},[33,1894,1895,1897,1899,1901,1903,1906,1908,1910,1912],{"class":35,"line":1339},[33,1896,382],{"class":43},[33,1898,385],{"class":173},[33,1900,1604],{"class":114},[33,1902,143],{"class":39},[33,1904,1905],{"class":50},"\"bio\"",[33,1907,396],{"class":114},[33,1909,143],{"class":39},[33,1911,401],{"class":50},[33,1913,1628],{"class":43},[33,1915,1916,1918,1920,1922,1924,1926,1928,1930],{"class":35,"line":1344},[33,1917,382],{"class":43},[33,1919,417],{"class":173},[33,1921,388],{"class":114},[33,1923,143],{"class":39},[33,1925,424],{"class":50},[33,1927,427],{"class":43},[33,1929,417],{"class":173},[33,1931,432],{"class":43},[33,1933,1934,1936,1938,1940,1942,1945,1948,1950,1953,1956,1959,1961,1964,1966],{"class":35,"line":1396},[33,1935,382],{"class":43},[33,1937,417],{"class":173},[33,1939,388],{"class":114},[33,1941,143],{"class":39},[33,1943,1944],{"class":50},"\"button\"",[33,1946,1947],{"class":114}," onClick",[33,1949,143],{"class":39},[33,1951,1952],{"class":43},"{() ",[33,1954,1955],{"class":39},"=>",[33,1957,1958],{"class":43}," formRef.current.",[33,1960,1834],{"class":114},[33,1962,1963],{"class":43},"()}>Reset\u003C\u002F",[33,1965,417],{"class":173},[33,1967,432],{"class":43},[33,1969,1971,1973,1975],{"class":35,"line":1970},49,[33,1972,438],{"class":43},[33,1974,368],{"class":173},[33,1976,432],{"class":43},[33,1978,1980],{"class":35,"line":1979},50,[33,1981,232],{"class":43},[33,1983,1985],{"class":35,"line":1984},51,[33,1986,238],{"class":43},[14,1988,1990],{"id":1989},"file-inputs-always-uncontrolled","File Inputs (Always Uncontrolled)",[19,1992,1994],{"filename":1993,"language":22},"file_inputs.js",[24,1995,1997],{"className":26,"code":1996,"language":22,"meta":28,"style":28},"import { useRef, useState } from 'react'\n\n\u002F\u002F File inputs are ALWAYS uncontrolled — browsers refuse to let JavaScript set\n\u002F\u002F the .value of a file input programmatically (security: prevents pre-filling\n\u002F\u002F a fake file path).\n\nfunction AvatarUpload() {\n  const fileRef = useRef(null)\n  const [preview, setPreview] = useState(null)\n\n  function handleFileChange(e) {\n    const file = e.target.files[0]\n    if (!file) return\n\n    if (!file.type.startsWith('image\u002F')) {\n      alert('Please select an image file')\n      e.target.value = ''\n      return\n    }\n    if (file.size > 5 * 1024 * 1024) {\n      alert('File too large (max 5MB)')\n      e.target.value = ''\n      return\n    }\n\n    setPreview(URL.createObjectURL(file))\n  }\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    const file = fileRef.current.files[0]\n    if (file) uploadAvatar(file)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput\n        type=\"file\"\n        ref={fileRef}\n        accept=\"image\u002F*\"\n        onChange={handleFileChange}\n      \u002F>\n      {preview && \u003Cimg src={preview} alt=\"Preview\" style={{ maxWidth: 200 }} \u002F>}\n      \u003Cbutton type=\"submit\">Upload\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n\nfunction MultiFileUpload() {\n  const filesRef = useRef(null)\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    const files = Array.from(filesRef.current.files)\n    const validFiles = files.filter(f => f.size \u003C 10 * 1024 * 1024)\n    uploadFiles(validFiles)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput type=\"file\" ref={filesRef} multiple accept=\".pdf,.doc,.docx\" \u002F>\n      \u003Cbutton type=\"submit\">Upload\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n\n\u002F\u002F ANTI-PATTERN: trying to make a file input controlled\nfunction BrokenFileInput() {\n  const [file, setFile] = useState(null)\n  return (\n    \u003Cinput\n      type=\"file\"\n      value={file}\n      onChange={e => setFile(e.target.value)}\n    \u002F>\n  )\n  \u002F\u002F React warning: \"File inputs are always uncontrolled.\"\n  \u002F\u002F e.target.value gives a fake path string — useless. Use e.target.files + ref.\n}\n",[30,1998,1999,2010,2014,2019,2024,2029,2033,2042,2059,2085,2089,2102,2119,2136,2140,2162,2174,2184,2189,2193,2218,2229,2237,2241,2245,2249,2268,2272,2276,2288,2296,2311,2324,2328,2332,2338,2350,2356,2366,2376,2386,2396,2401,2444,2463,2471,2475,2479,2483,2492,2509,2513,2526,2535,2553,2594,2603,2608,2613,2620,2633,2667,2686,2695,2700,2705,2710,2716,2726,2753,2760,2767,2776,2786,2804,2809,2814,2820,2826],{"__ignoreMap":28},[33,2000,2001,2003,2006,2008],{"class":35,"line":36},[33,2002,40],{"class":39},[33,2004,2005],{"class":43}," { useRef, useState } ",[33,2007,47],{"class":39},[33,2009,51],{"class":50},[33,2011,2012],{"class":35,"line":54},[33,2013,58],{"emptyLinePlaceholder":57},[33,2015,2016],{"class":35,"line":61},[33,2017,2018],{"class":64},"\u002F\u002F File inputs are ALWAYS uncontrolled — browsers refuse to let JavaScript set\n",[33,2020,2021],{"class":35,"line":68},[33,2022,2023],{"class":64},"\u002F\u002F the .value of a file input programmatically (security: prevents pre-filling\n",[33,2025,2026],{"class":35,"line":74},[33,2027,2028],{"class":64},"\u002F\u002F a fake file path).\n",[33,2030,2031],{"class":35,"line":79},[33,2032,58],{"emptyLinePlaceholder":57},[33,2034,2035,2037,2040],{"class":35,"line":85},[33,2036,111],{"class":39},[33,2038,2039],{"class":114}," AvatarUpload",[33,2041,118],{"class":43},[33,2043,2044,2046,2049,2051,2053,2055,2057],{"class":35,"line":91},[33,2045,124],{"class":39},[33,2047,2048],{"class":130}," fileRef",[33,2050,287],{"class":39},[33,2052,290],{"class":114},[33,2054,149],{"class":43},[33,2056,295],{"class":130},[33,2058,155],{"class":43},[33,2060,2061,2063,2065,2068,2070,2073,2075,2077,2079,2081,2083],{"class":35,"line":97},[33,2062,124],{"class":39},[33,2064,127],{"class":43},[33,2066,2067],{"class":130},"preview",[33,2069,134],{"class":43},[33,2071,2072],{"class":130},"setPreview",[33,2074,140],{"class":43},[33,2076,143],{"class":39},[33,2078,146],{"class":114},[33,2080,149],{"class":43},[33,2082,295],{"class":130},[33,2084,155],{"class":43},[33,2086,2087],{"class":35,"line":103},[33,2088,58],{"emptyLinePlaceholder":57},[33,2090,2091,2093,2096,2098,2100],{"class":35,"line":108},[33,2092,308],{"class":39},[33,2094,2095],{"class":114}," handleFileChange",[33,2097,149],{"class":43},[33,2099,211],{"class":210},[33,2101,318],{"class":43},[33,2103,2104,2106,2109,2111,2114,2116],{"class":35,"line":121},[33,2105,851],{"class":39},[33,2107,2108],{"class":130}," file",[33,2110,287],{"class":39},[33,2112,2113],{"class":43}," e.target.files[",[33,2115,890],{"class":130},[33,2117,2118],{"class":43},"]\n",[33,2120,2121,2124,2127,2130,2133],{"class":35,"line":158},[33,2122,2123],{"class":39},"    if",[33,2125,2126],{"class":43}," (",[33,2128,2129],{"class":39},"!",[33,2131,2132],{"class":43},"file) ",[33,2134,2135],{"class":39},"return\n",[33,2137,2138],{"class":35,"line":167},[33,2139,58],{"emptyLinePlaceholder":57},[33,2141,2142,2144,2146,2148,2151,2154,2156,2159],{"class":35,"line":177},[33,2143,2123],{"class":39},[33,2145,2126],{"class":43},[33,2147,2129],{"class":39},[33,2149,2150],{"class":43},"file.type.",[33,2152,2153],{"class":114},"startsWith",[33,2155,149],{"class":43},[33,2157,2158],{"class":50},"'image\u002F'",[33,2160,2161],{"class":43},")) {\n",[33,2163,2164,2167,2169,2172],{"class":35,"line":188},[33,2165,2166],{"class":114},"      alert",[33,2168,149],{"class":43},[33,2170,2171],{"class":50},"'Please select an image file'",[33,2173,155],{"class":43},[33,2175,2176,2179,2181],{"class":35,"line":199},[33,2177,2178],{"class":43},"      e.target.value ",[33,2180,143],{"class":39},[33,2182,2183],{"class":50}," ''\n",[33,2185,2186],{"class":35,"line":223},[33,2187,2188],{"class":39},"      return\n",[33,2190,2191],{"class":35,"line":229},[33,2192,1555],{"class":43},[33,2194,2195,2197,2200,2203,2206,2209,2212,2214,2216],{"class":35,"line":235},[33,2196,2123],{"class":39},[33,2198,2199],{"class":43}," (file.size ",[33,2201,2202],{"class":39},">",[33,2204,2205],{"class":130}," 5",[33,2207,2208],{"class":39}," *",[33,2210,2211],{"class":130}," 1024",[33,2213,2208],{"class":39},[33,2215,2211],{"class":130},[33,2217,318],{"class":43},[33,2219,2220,2222,2224,2227],{"class":35,"line":241},[33,2221,2166],{"class":114},[33,2223,149],{"class":43},[33,2225,2226],{"class":50},"'File too large (max 5MB)'",[33,2228,155],{"class":43},[33,2230,2231,2233,2235],{"class":35,"line":246},[33,2232,2178],{"class":43},[33,2234,143],{"class":39},[33,2236,2183],{"class":50},[33,2238,2239],{"class":35,"line":252},[33,2240,2188],{"class":39},[33,2242,2243],{"class":35,"line":258},[33,2244,1555],{"class":43},[33,2246,2247],{"class":35,"line":264},[33,2248,58],{"emptyLinePlaceholder":57},[33,2250,2251,2254,2256,2259,2262,2265],{"class":35,"line":269},[33,2252,2253],{"class":114},"    setPreview",[33,2255,149],{"class":43},[33,2257,2258],{"class":130},"URL",[33,2260,2261],{"class":43},".",[33,2263,2264],{"class":114},"createObjectURL",[33,2266,2267],{"class":43},"(file))\n",[33,2269,2270],{"class":35,"line":279},[33,2271,348],{"class":43},[33,2273,2274],{"class":35,"line":300},[33,2275,58],{"emptyLinePlaceholder":57},[33,2277,2278,2280,2282,2284,2286],{"class":35,"line":305},[33,2279,308],{"class":39},[33,2281,311],{"class":114},[33,2283,149],{"class":43},[33,2285,211],{"class":210},[33,2287,318],{"class":43},[33,2289,2290,2292,2294],{"class":35,"line":321},[33,2291,324],{"class":43},[33,2293,327],{"class":114},[33,2295,330],{"class":43},[33,2297,2298,2300,2302,2304,2307,2309],{"class":35,"line":333},[33,2299,851],{"class":39},[33,2301,2108],{"class":130},[33,2303,287],{"class":39},[33,2305,2306],{"class":43}," fileRef.current.files[",[33,2308,890],{"class":130},[33,2310,2118],{"class":43},[33,2312,2313,2315,2318,2321],{"class":35,"line":345},[33,2314,2123],{"class":39},[33,2316,2317],{"class":43}," (file) ",[33,2319,2320],{"class":114},"uploadAvatar",[33,2322,2323],{"class":43},"(file)\n",[33,2325,2326],{"class":35,"line":351},[33,2327,348],{"class":43},[33,2329,2330],{"class":35,"line":356},[33,2331,58],{"emptyLinePlaceholder":57},[33,2333,2334,2336],{"class":35,"line":363},[33,2335,161],{"class":39},[33,2337,164],{"class":43},[33,2339,2340,2342,2344,2346,2348],{"class":35,"line":379},[33,2341,170],{"class":43},[33,2343,368],{"class":173},[33,2345,371],{"class":114},[33,2347,143],{"class":39},[33,2349,376],{"class":43},[33,2351,2352,2354],{"class":35,"line":412},[33,2353,382],{"class":43},[33,2355,174],{"class":173},[33,2357,2358,2361,2363],{"class":35,"line":435},[33,2359,2360],{"class":114},"        type",[33,2362,143],{"class":39},[33,2364,2365],{"class":50},"\"file\"\n",[33,2367,2368,2371,2373],{"class":35,"line":445},[33,2369,2370],{"class":114},"        ref",[33,2372,143],{"class":39},[33,2374,2375],{"class":43},"{fileRef}\n",[33,2377,2378,2381,2383],{"class":35,"line":450},[33,2379,2380],{"class":114},"        accept",[33,2382,143],{"class":39},[33,2384,2385],{"class":50},"\"image\u002F*\"\n",[33,2387,2388,2391,2393],{"class":35,"line":1200},[33,2389,2390],{"class":114},"        onChange",[33,2392,143],{"class":39},[33,2394,2395],{"class":43},"{handleFileChange}\n",[33,2397,2398],{"class":35,"line":1227},[33,2399,2400],{"class":43},"      \u002F>\n",[33,2402,2403,2406,2409,2411,2414,2417,2419,2422,2425,2427,2430,2433,2435,2438,2441],{"class":35,"line":1240},[33,2404,2405],{"class":43},"      {preview ",[33,2407,2408],{"class":39},"&&",[33,2410,550],{"class":43},[33,2412,2413],{"class":173},"img",[33,2415,2416],{"class":114}," src",[33,2418,143],{"class":39},[33,2420,2421],{"class":43},"{preview} ",[33,2423,2424],{"class":114},"alt",[33,2426,143],{"class":39},[33,2428,2429],{"class":50},"\"Preview\"",[33,2431,2432],{"class":114}," style",[33,2434,143],{"class":39},[33,2436,2437],{"class":43},"{{ maxWidth: ",[33,2439,2440],{"class":130},"200",[33,2442,2443],{"class":43}," }} \u002F>}\n",[33,2445,2446,2448,2450,2452,2454,2456,2459,2461],{"class":35,"line":1270},[33,2447,382],{"class":43},[33,2449,417],{"class":173},[33,2451,388],{"class":114},[33,2453,143],{"class":39},[33,2455,424],{"class":50},[33,2457,2458],{"class":43},">Upload\u003C\u002F",[33,2460,417],{"class":173},[33,2462,432],{"class":43},[33,2464,2465,2467,2469],{"class":35,"line":1330},[33,2466,438],{"class":43},[33,2468,368],{"class":173},[33,2470,432],{"class":43},[33,2472,2473],{"class":35,"line":1339},[33,2474,232],{"class":43},[33,2476,2477],{"class":35,"line":1344},[33,2478,238],{"class":43},[33,2480,2481],{"class":35,"line":1396},[33,2482,58],{"emptyLinePlaceholder":57},[33,2484,2485,2487,2490],{"class":35,"line":1970},[33,2486,111],{"class":39},[33,2488,2489],{"class":114}," MultiFileUpload",[33,2491,118],{"class":43},[33,2493,2494,2496,2499,2501,2503,2505,2507],{"class":35,"line":1979},[33,2495,124],{"class":39},[33,2497,2498],{"class":130}," filesRef",[33,2500,287],{"class":39},[33,2502,290],{"class":114},[33,2504,149],{"class":43},[33,2506,295],{"class":130},[33,2508,155],{"class":43},[33,2510,2511],{"class":35,"line":1984},[33,2512,58],{"emptyLinePlaceholder":57},[33,2514,2516,2518,2520,2522,2524],{"class":35,"line":2515},52,[33,2517,308],{"class":39},[33,2519,311],{"class":114},[33,2521,149],{"class":43},[33,2523,211],{"class":210},[33,2525,318],{"class":43},[33,2527,2529,2531,2533],{"class":35,"line":2528},53,[33,2530,324],{"class":43},[33,2532,327],{"class":114},[33,2534,330],{"class":43},[33,2536,2538,2540,2543,2545,2548,2550],{"class":35,"line":2537},54,[33,2539,851],{"class":39},[33,2541,2542],{"class":130}," files",[33,2544,287],{"class":39},[33,2546,2547],{"class":43}," Array.",[33,2549,47],{"class":114},[33,2551,2552],{"class":43},"(filesRef.current.files)\n",[33,2554,2556,2558,2561,2563,2566,2568,2570,2573,2575,2578,2581,2584,2586,2588,2590,2592],{"class":35,"line":2555},55,[33,2557,851],{"class":39},[33,2559,2560],{"class":130}," validFiles",[33,2562,287],{"class":39},[33,2564,2565],{"class":43}," files.",[33,2567,995],{"class":114},[33,2569,149],{"class":43},[33,2571,2572],{"class":210},"f",[33,2574,214],{"class":39},[33,2576,2577],{"class":43}," f.size ",[33,2579,2580],{"class":39},"\u003C",[33,2582,2583],{"class":130}," 10",[33,2585,2208],{"class":39},[33,2587,2211],{"class":130},[33,2589,2208],{"class":39},[33,2591,2211],{"class":130},[33,2593,155],{"class":43},[33,2595,2597,2600],{"class":35,"line":2596},56,[33,2598,2599],{"class":114},"    uploadFiles",[33,2601,2602],{"class":43},"(validFiles)\n",[33,2604,2606],{"class":35,"line":2605},57,[33,2607,348],{"class":43},[33,2609,2611],{"class":35,"line":2610},58,[33,2612,58],{"emptyLinePlaceholder":57},[33,2614,2616,2618],{"class":35,"line":2615},59,[33,2617,161],{"class":39},[33,2619,164],{"class":43},[33,2621,2623,2625,2627,2629,2631],{"class":35,"line":2622},60,[33,2624,170],{"class":43},[33,2626,368],{"class":173},[33,2628,371],{"class":114},[33,2630,143],{"class":39},[33,2632,376],{"class":43},[33,2634,2636,2638,2640,2642,2644,2647,2649,2651,2654,2657,2660,2662,2665],{"class":35,"line":2635},61,[33,2637,382],{"class":43},[33,2639,385],{"class":173},[33,2641,388],{"class":114},[33,2643,143],{"class":39},[33,2645,2646],{"class":50},"\"file\"",[33,2648,404],{"class":114},[33,2650,143],{"class":39},[33,2652,2653],{"class":43},"{filesRef} ",[33,2655,2656],{"class":114},"multiple",[33,2658,2659],{"class":114}," accept",[33,2661,143],{"class":39},[33,2663,2664],{"class":50},"\".pdf,.doc,.docx\"",[33,2666,1628],{"class":43},[33,2668,2670,2672,2674,2676,2678,2680,2682,2684],{"class":35,"line":2669},62,[33,2671,382],{"class":43},[33,2673,417],{"class":173},[33,2675,388],{"class":114},[33,2677,143],{"class":39},[33,2679,424],{"class":50},[33,2681,2458],{"class":43},[33,2683,417],{"class":173},[33,2685,432],{"class":43},[33,2687,2689,2691,2693],{"class":35,"line":2688},63,[33,2690,438],{"class":43},[33,2692,368],{"class":173},[33,2694,432],{"class":43},[33,2696,2698],{"class":35,"line":2697},64,[33,2699,232],{"class":43},[33,2701,2703],{"class":35,"line":2702},65,[33,2704,238],{"class":43},[33,2706,2708],{"class":35,"line":2707},66,[33,2709,58],{"emptyLinePlaceholder":57},[33,2711,2713],{"class":35,"line":2712},67,[33,2714,2715],{"class":64},"\u002F\u002F ANTI-PATTERN: trying to make a file input controlled\n",[33,2717,2719,2721,2724],{"class":35,"line":2718},68,[33,2720,111],{"class":39},[33,2722,2723],{"class":114}," BrokenFileInput",[33,2725,118],{"class":43},[33,2727,2729,2731,2733,2736,2738,2741,2743,2745,2747,2749,2751],{"class":35,"line":2728},69,[33,2730,124],{"class":39},[33,2732,127],{"class":43},[33,2734,2735],{"class":130},"file",[33,2737,134],{"class":43},[33,2739,2740],{"class":130},"setFile",[33,2742,140],{"class":43},[33,2744,143],{"class":39},[33,2746,146],{"class":114},[33,2748,149],{"class":43},[33,2750,295],{"class":130},[33,2752,155],{"class":43},[33,2754,2756,2758],{"class":35,"line":2755},70,[33,2757,161],{"class":39},[33,2759,164],{"class":43},[33,2761,2763,2765],{"class":35,"line":2762},71,[33,2764,170],{"class":43},[33,2766,174],{"class":173},[33,2768,2770,2772,2774],{"class":35,"line":2769},72,[33,2771,180],{"class":114},[33,2773,143],{"class":39},[33,2775,2365],{"class":50},[33,2777,2779,2781,2783],{"class":35,"line":2778},73,[33,2780,191],{"class":114},[33,2782,143],{"class":39},[33,2784,2785],{"class":43},"{file}\n",[33,2787,2789,2791,2793,2795,2797,2799,2802],{"class":35,"line":2788},74,[33,2790,202],{"class":114},[33,2792,143],{"class":39},[33,2794,207],{"class":43},[33,2796,211],{"class":210},[33,2798,214],{"class":39},[33,2800,2801],{"class":114}," setFile",[33,2803,220],{"class":43},[33,2805,2807],{"class":35,"line":2806},75,[33,2808,226],{"class":43},[33,2810,2812],{"class":35,"line":2811},76,[33,2813,232],{"class":43},[33,2815,2817],{"class":35,"line":2816},77,[33,2818,2819],{"class":64},"  \u002F\u002F React warning: \"File inputs are always uncontrolled.\"\n",[33,2821,2823],{"class":35,"line":2822},78,[33,2824,2825],{"class":64},"  \u002F\u002F e.target.value gives a fake path string — useless. Use e.target.files + ref.\n",[33,2827,2829],{"class":35,"line":2828},79,[33,2830,238],{"class":43},[14,2832,2834],{"id":2833},"defaultvalues-and-defaultvalue-gotchas","defaultValues and defaultValue Gotchas",[19,2836,2838],{"filename":2837,"language":22},"defaultvalues.js",[24,2839,2841],{"className":26,"code":2840,"language":22,"meta":28,"style":28},"import { useRef, useState, useEffect } from 'react'\n\n\u002F\u002F defaultValue\u002FdefaultChecked set the INITIAL DOM value on mount, then React\n\u002F\u002F stops touching the input. Changing defaultValue on re-render does NOT update\n\u002F\u002F the input's current value.\n\nfunction PrefilledForm({ user }) {\n  return (\n    \u003Cform>\n      \u003Cinput name=\"name\" defaultValue={user.name} \u002F>\n      \u003Cinput name=\"email\" defaultValue={user.email} \u002F>\n      {\u002F* Set ONCE on mount. If user prop changes after mount, inputs do NOT update. *\u002F}\n    \u003C\u002Fform>\n  )\n}\n\n\u002F\u002F FIX 1: Force remount with key when the data source changes\nfunction EditProfileKeyRemount({ user }) {\n  return \u003Cinput key={user.id} defaultValue={user.name} \u002F>\n  \u002F\u002F Changing user.id → key changes → remount → defaultValue re-applies.\n}\n\n\u002F\u002F FIX 2: Use controlled input — value always reflects current prop\u002Fstate\nfunction EditProfileControlled({ user }) {\n  const [name, setName] = useState(user.name)\n  useEffect(() => setName(user.name), [user.name])\n  return \u003Cinput value={name} onChange={e => setName(e.target.value)} \u002F>\n}\n\n\u002F\u002F defaultChecked for checkboxes and radios\nfunction CheckboxUncontrolled() {\n  return (\n    \u003Clabel>\n      \u003Cinput type=\"checkbox\" defaultChecked={true} \u002F>\n      Subscribe to newsletter\n    \u003C\u002Flabel>\n  )\n}\n\n\u002F\u002F ANTI-PATTERN: using value\u002FdefaultValue on a checkbox\nfunction BrokenCheckbox() {\n  return \u003Cinput type=\"checkbox\" value={true} \u002F>\n  \u002F\u002F `value` on a checkbox sets the FORM SUBMISSION value, NOT whether it's checked.\n  \u002F\u002F Use `checked` (controlled) or `defaultChecked` (uncontrolled).\n}\n",[30,2842,2843,2854,2858,2863,2868,2873,2877,2891,2897,2905,2924,2943,2953,2961,2965,2969,2973,2978,2991,3014,3019,3023,3027,3032,3045,3067,3083,3112,3116,3120,3125,3134,3140,3149,3174,3179,3187,3191,3195,3199,3204,3213,3237,3242,3247],{"__ignoreMap":28},[33,2844,2845,2847,2850,2852],{"class":35,"line":36},[33,2846,40],{"class":39},[33,2848,2849],{"class":43}," { useRef, useState, useEffect } ",[33,2851,47],{"class":39},[33,2853,51],{"class":50},[33,2855,2856],{"class":35,"line":54},[33,2857,58],{"emptyLinePlaceholder":57},[33,2859,2860],{"class":35,"line":61},[33,2861,2862],{"class":64},"\u002F\u002F defaultValue\u002FdefaultChecked set the INITIAL DOM value on mount, then React\n",[33,2864,2865],{"class":35,"line":68},[33,2866,2867],{"class":64},"\u002F\u002F stops touching the input. Changing defaultValue on re-render does NOT update\n",[33,2869,2870],{"class":35,"line":74},[33,2871,2872],{"class":64},"\u002F\u002F the input's current value.\n",[33,2874,2875],{"class":35,"line":79},[33,2876,58],{"emptyLinePlaceholder":57},[33,2878,2879,2881,2884,2886,2889],{"class":35,"line":85},[33,2880,111],{"class":39},[33,2882,2883],{"class":114}," PrefilledForm",[33,2885,593],{"class":43},[33,2887,2888],{"class":210},"user",[33,2890,599],{"class":43},[33,2892,2893,2895],{"class":35,"line":91},[33,2894,161],{"class":39},[33,2896,164],{"class":43},[33,2898,2899,2901,2903],{"class":35,"line":97},[33,2900,170],{"class":43},[33,2902,368],{"class":173},[33,2904,432],{"class":43},[33,2906,2907,2909,2911,2913,2915,2917,2919,2921],{"class":35,"line":103},[33,2908,382],{"class":43},[33,2910,385],{"class":173},[33,2912,1604],{"class":114},[33,2914,143],{"class":39},[33,2916,1609],{"class":50},[33,2918,396],{"class":114},[33,2920,143],{"class":39},[33,2922,2923],{"class":43},"{user.name} \u002F>\n",[33,2925,2926,2928,2930,2932,2934,2936,2938,2940],{"class":35,"line":108},[33,2927,382],{"class":43},[33,2929,385],{"class":173},[33,2931,1604],{"class":114},[33,2933,143],{"class":39},[33,2935,1641],{"class":50},[33,2937,396],{"class":114},[33,2939,143],{"class":39},[33,2941,2942],{"class":43},"{user.email} \u002F>\n",[33,2944,2945,2948,2951],{"class":35,"line":121},[33,2946,2947],{"class":43},"      {",[33,2949,2950],{"class":64},"\u002F* Set ONCE on mount. If user prop changes after mount, inputs do NOT update. *\u002F",[33,2952,238],{"class":43},[33,2954,2955,2957,2959],{"class":35,"line":158},[33,2956,438],{"class":43},[33,2958,368],{"class":173},[33,2960,432],{"class":43},[33,2962,2963],{"class":35,"line":167},[33,2964,232],{"class":43},[33,2966,2967],{"class":35,"line":177},[33,2968,238],{"class":43},[33,2970,2971],{"class":35,"line":188},[33,2972,58],{"emptyLinePlaceholder":57},[33,2974,2975],{"class":35,"line":199},[33,2976,2977],{"class":64},"\u002F\u002F FIX 1: Force remount with key when the data source changes\n",[33,2979,2980,2982,2985,2987,2989],{"class":35,"line":223},[33,2981,111],{"class":39},[33,2983,2984],{"class":114}," EditProfileKeyRemount",[33,2986,593],{"class":43},[33,2988,2888],{"class":210},[33,2990,599],{"class":43},[33,2992,2993,2995,2997,2999,3002,3004,3007,3010,3012],{"class":35,"line":229},[33,2994,161],{"class":39},[33,2996,550],{"class":43},[33,2998,385],{"class":173},[33,3000,3001],{"class":114}," key",[33,3003,143],{"class":39},[33,3005,3006],{"class":43},"{user.id} ",[33,3008,3009],{"class":114},"defaultValue",[33,3011,143],{"class":39},[33,3013,2923],{"class":43},[33,3015,3016],{"class":35,"line":235},[33,3017,3018],{"class":64},"  \u002F\u002F Changing user.id → key changes → remount → defaultValue re-applies.\n",[33,3020,3021],{"class":35,"line":241},[33,3022,238],{"class":43},[33,3024,3025],{"class":35,"line":246},[33,3026,58],{"emptyLinePlaceholder":57},[33,3028,3029],{"class":35,"line":252},[33,3030,3031],{"class":64},"\u002F\u002F FIX 2: Use controlled input — value always reflects current prop\u002Fstate\n",[33,3033,3034,3036,3039,3041,3043],{"class":35,"line":258},[33,3035,111],{"class":39},[33,3037,3038],{"class":114}," EditProfileControlled",[33,3040,593],{"class":43},[33,3042,2888],{"class":210},[33,3044,599],{"class":43},[33,3046,3047,3049,3051,3053,3055,3058,3060,3062,3064],{"class":35,"line":264},[33,3048,124],{"class":39},[33,3050,127],{"class":43},[33,3052,531],{"class":130},[33,3054,134],{"class":43},[33,3056,3057],{"class":130},"setName",[33,3059,140],{"class":43},[33,3061,143],{"class":39},[33,3063,146],{"class":114},[33,3065,3066],{"class":43},"(user.name)\n",[33,3068,3069,3072,3075,3077,3080],{"class":35,"line":269},[33,3070,3071],{"class":114},"  useEffect",[33,3073,3074],{"class":43},"(() ",[33,3076,1955],{"class":39},[33,3078,3079],{"class":114}," setName",[33,3081,3082],{"class":43},"(user.name), [user.name])\n",[33,3084,3085,3087,3089,3091,3093,3095,3098,3100,3102,3104,3106,3108,3110],{"class":35,"line":279},[33,3086,161],{"class":39},[33,3088,550],{"class":43},[33,3090,385],{"class":173},[33,3092,555],{"class":114},[33,3094,143],{"class":39},[33,3096,3097],{"class":43},"{name} ",[33,3099,643],{"class":114},[33,3101,143],{"class":39},[33,3103,207],{"class":43},[33,3105,211],{"class":210},[33,3107,214],{"class":39},[33,3109,3079],{"class":114},[33,3111,657],{"class":43},[33,3113,3114],{"class":35,"line":300},[33,3115,238],{"class":43},[33,3117,3118],{"class":35,"line":305},[33,3119,58],{"emptyLinePlaceholder":57},[33,3121,3122],{"class":35,"line":321},[33,3123,3124],{"class":64},"\u002F\u002F defaultChecked for checkboxes and radios\n",[33,3126,3127,3129,3132],{"class":35,"line":333},[33,3128,111],{"class":39},[33,3130,3131],{"class":114}," CheckboxUncontrolled",[33,3133,118],{"class":43},[33,3135,3136,3138],{"class":35,"line":345},[33,3137,161],{"class":39},[33,3139,164],{"class":43},[33,3141,3142,3144,3147],{"class":35,"line":351},[33,3143,170],{"class":43},[33,3145,3146],{"class":173},"label",[33,3148,432],{"class":43},[33,3150,3151,3153,3155,3157,3159,3162,3165,3167,3169,3172],{"class":35,"line":356},[33,3152,382],{"class":43},[33,3154,385],{"class":173},[33,3156,388],{"class":114},[33,3158,143],{"class":39},[33,3160,3161],{"class":50},"\"checkbox\"",[33,3163,3164],{"class":114}," defaultChecked",[33,3166,143],{"class":39},[33,3168,207],{"class":43},[33,3170,3171],{"class":130},"true",[33,3173,1393],{"class":43},[33,3175,3176],{"class":35,"line":363},[33,3177,3178],{"class":43},"      Subscribe to newsletter\n",[33,3180,3181,3183,3185],{"class":35,"line":379},[33,3182,438],{"class":43},[33,3184,3146],{"class":173},[33,3186,432],{"class":43},[33,3188,3189],{"class":35,"line":412},[33,3190,232],{"class":43},[33,3192,3193],{"class":35,"line":435},[33,3194,238],{"class":43},[33,3196,3197],{"class":35,"line":445},[33,3198,58],{"emptyLinePlaceholder":57},[33,3200,3201],{"class":35,"line":450},[33,3202,3203],{"class":64},"\u002F\u002F ANTI-PATTERN: using value\u002FdefaultValue on a checkbox\n",[33,3205,3206,3208,3211],{"class":35,"line":1200},[33,3207,111],{"class":39},[33,3209,3210],{"class":114}," BrokenCheckbox",[33,3212,118],{"class":43},[33,3214,3215,3217,3219,3221,3223,3225,3227,3229,3231,3233,3235],{"class":35,"line":1227},[33,3216,161],{"class":39},[33,3218,550],{"class":43},[33,3220,385],{"class":173},[33,3222,388],{"class":114},[33,3224,143],{"class":39},[33,3226,3161],{"class":50},[33,3228,555],{"class":114},[33,3230,143],{"class":39},[33,3232,207],{"class":43},[33,3234,3171],{"class":130},[33,3236,1393],{"class":43},[33,3238,3239],{"class":35,"line":1240},[33,3240,3241],{"class":64},"  \u002F\u002F `value` on a checkbox sets the FORM SUBMISSION value, NOT whether it's checked.\n",[33,3243,3244],{"class":35,"line":1270},[33,3245,3246],{"class":64},"  \u002F\u002F Use `checked` (controlled) or `defaultChecked` (uncontrolled).\n",[33,3248,3249],{"class":35,"line":1330},[33,3250,238],{"class":43},[14,3252,3254],{"id":3253},"form-submission-with-formdata","Form Submission with FormData",[19,3256,3258],{"filename":3257,"language":22},"formdata_submission.js",[24,3259,3261],{"className":26,"code":3260,"language":22,"meta":28,"style":28},"import { useRef, useState } from 'react'\n\n\u002F\u002F FormData reads all named fields from a \u003Cform> in one call — works with both\n\u002F\u002F controlled and uncontrolled inputs. The `name` attribute on each field is required.\n\nfunction SignupFormFormData() {\n  const formRef = useRef(null)\n  const [submitting, setSubmitting] = useState(false)\n\n  async function handleSubmit(e) {\n    e.preventDefault()\n    const formData = new FormData(e.target)\n\n    const data = Object.fromEntries(formData.entries())\n    \u002F\u002F { name: \"Alice\", email: \"alice@example.com\", password: \"secret\" }\n\n    \u002F\u002F For multi-value fields (checkboxes with same name), use getAll:\n    \u002F\u002F const interests = formData.getAll('interests')  → [\"sports\", \"music\"]\n\n    setSubmitting(true)\n    try {\n      await api.signup(data)\n      formRef.current.reset()\n    } catch (err) {\n      console.error('Signup failed:', err)\n    } finally {\n      setSubmitting(false)\n    }\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit} ref={formRef}>\n      \u003Cinput name=\"name\" type=\"text\" required \u002F>\n      \u003Cinput name=\"email\" type=\"email\" required \u002F>\n      \u003Cinput name=\"password\" type=\"password\" required \u002F>\n\n      \u003Clabel>\u003Cinput type=\"checkbox\" name=\"interests\" value=\"sports\" \u002F> Sports\u003C\u002Flabel>\n      \u003Clabel>\u003Cinput type=\"checkbox\" name=\"interests\" value=\"music\" \u002F> Music\u003C\u002Flabel>\n      \u003Clabel>\u003Cinput type=\"checkbox\" name=\"interests\" value=\"reading\" \u002F> Reading\u003C\u002Flabel>\n\n      \u003Cbutton type=\"submit\" disabled={submitting}>\n        {submitting ? 'Creating account…' : 'Sign Up'}\n      \u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n\n\u002F\u002F Sending FormData directly as multipart\u002Fform-data (for file uploads)\nfunction UploadWithFormData() {\n  async function handleSubmit(e) {\n    e.preventDefault()\n    const formData = new FormData(e.target)\n    \u002F\u002F Don't set Content-Type — the browser sets it automatically with the\n    \u002F\u002F correct multipart boundary when you pass FormData to fetch.\n    const res = await fetch('\u002Fapi\u002Fupload', {\n      method: 'POST',\n      body: formData,\n    })\n    return res.json()\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput name=\"title\" type=\"text\" required \u002F>\n      \u003Cinput name=\"file\" type=\"file\" required \u002F>\n      \u003Cbutton type=\"submit\">Upload\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n",[30,3262,3263,3273,3277,3282,3287,3291,3300,3316,3343,3347,3363,3371,3385,3389,3411,3416,3420,3425,3430,3434,3445,3452,3465,3474,3485,3501,3510,3521,3525,3529,3533,3539,3557,3580,3602,3625,3629,3667,3703,3739,3743,3763,3781,3790,3798,3802,3806,3810,3815,3824,3838,3846,3860,3865,3870,3893,3904,3909,3914,3927,3931,3935,3941,3953,3976,3998,4016,4024,4028],{"__ignoreMap":28},[33,3264,3265,3267,3269,3271],{"class":35,"line":36},[33,3266,40],{"class":39},[33,3268,2005],{"class":43},[33,3270,47],{"class":39},[33,3272,51],{"class":50},[33,3274,3275],{"class":35,"line":54},[33,3276,58],{"emptyLinePlaceholder":57},[33,3278,3279],{"class":35,"line":61},[33,3280,3281],{"class":64},"\u002F\u002F FormData reads all named fields from a \u003Cform> in one call — works with both\n",[33,3283,3284],{"class":35,"line":68},[33,3285,3286],{"class":64},"\u002F\u002F controlled and uncontrolled inputs. The `name` attribute on each field is required.\n",[33,3288,3289],{"class":35,"line":74},[33,3290,58],{"emptyLinePlaceholder":57},[33,3292,3293,3295,3298],{"class":35,"line":79},[33,3294,111],{"class":39},[33,3296,3297],{"class":114}," SignupFormFormData",[33,3299,118],{"class":43},[33,3301,3302,3304,3306,3308,3310,3312,3314],{"class":35,"line":85},[33,3303,124],{"class":39},[33,3305,1760],{"class":130},[33,3307,287],{"class":39},[33,3309,290],{"class":114},[33,3311,149],{"class":43},[33,3313,295],{"class":130},[33,3315,155],{"class":43},[33,3317,3318,3320,3322,3325,3327,3330,3332,3334,3336,3338,3341],{"class":35,"line":91},[33,3319,124],{"class":39},[33,3321,127],{"class":43},[33,3323,3324],{"class":130},"submitting",[33,3326,134],{"class":43},[33,3328,3329],{"class":130},"setSubmitting",[33,3331,140],{"class":43},[33,3333,143],{"class":39},[33,3335,146],{"class":114},[33,3337,149],{"class":43},[33,3339,3340],{"class":130},"false",[33,3342,155],{"class":43},[33,3344,3345],{"class":35,"line":97},[33,3346,58],{"emptyLinePlaceholder":57},[33,3348,3349,3352,3355,3357,3359,3361],{"class":35,"line":103},[33,3350,3351],{"class":39},"  async",[33,3353,3354],{"class":39}," function",[33,3356,311],{"class":114},[33,3358,149],{"class":43},[33,3360,211],{"class":210},[33,3362,318],{"class":43},[33,3364,3365,3367,3369],{"class":35,"line":108},[33,3366,324],{"class":43},[33,3368,327],{"class":114},[33,3370,330],{"class":43},[33,3372,3373,3375,3377,3379,3381,3383],{"class":35,"line":121},[33,3374,851],{"class":39},[33,3376,1801],{"class":130},[33,3378,287],{"class":39},[33,3380,1806],{"class":39},[33,3382,1809],{"class":114},[33,3384,1812],{"class":43},[33,3386,3387],{"class":35,"line":158},[33,3388,58],{"emptyLinePlaceholder":57},[33,3390,3391,3393,3395,3397,3400,3402,3405,3408],{"class":35,"line":167},[33,3392,851],{"class":39},[33,3394,1530],{"class":130},[33,3396,287],{"class":39},[33,3398,3399],{"class":43}," Object.",[33,3401,1823],{"class":114},[33,3403,3404],{"class":43},"(formData.",[33,3406,3407],{"class":114},"entries",[33,3409,3410],{"class":43},"())\n",[33,3412,3413],{"class":35,"line":177},[33,3414,3415],{"class":64},"    \u002F\u002F { name: \"Alice\", email: \"alice@example.com\", password: \"secret\" }\n",[33,3417,3418],{"class":35,"line":188},[33,3419,58],{"emptyLinePlaceholder":57},[33,3421,3422],{"class":35,"line":199},[33,3423,3424],{"class":64},"    \u002F\u002F For multi-value fields (checkboxes with same name), use getAll:\n",[33,3426,3427],{"class":35,"line":223},[33,3428,3429],{"class":64},"    \u002F\u002F const interests = formData.getAll('interests')  → [\"sports\", \"music\"]\n",[33,3431,3432],{"class":35,"line":229},[33,3433,58],{"emptyLinePlaceholder":57},[33,3435,3436,3439,3441,3443],{"class":35,"line":235},[33,3437,3438],{"class":114},"    setSubmitting",[33,3440,149],{"class":43},[33,3442,3171],{"class":130},[33,3444,155],{"class":43},[33,3446,3447,3450],{"class":35,"line":241},[33,3448,3449],{"class":39},"    try",[33,3451,1535],{"class":43},[33,3453,3454,3457,3460,3463],{"class":35,"line":246},[33,3455,3456],{"class":39},"      await",[33,3458,3459],{"class":43}," api.",[33,3461,3462],{"class":114},"signup",[33,3464,1563],{"class":43},[33,3466,3467,3470,3472],{"class":35,"line":252},[33,3468,3469],{"class":43},"      formRef.current.",[33,3471,1834],{"class":114},[33,3473,330],{"class":43},[33,3475,3476,3479,3482],{"class":35,"line":258},[33,3477,3478],{"class":43},"    } ",[33,3480,3481],{"class":39},"catch",[33,3483,3484],{"class":43}," (err) {\n",[33,3486,3487,3490,3493,3495,3498],{"class":35,"line":264},[33,3488,3489],{"class":43},"      console.",[33,3491,3492],{"class":114},"error",[33,3494,149],{"class":43},[33,3496,3497],{"class":50},"'Signup failed:'",[33,3499,3500],{"class":43},", err)\n",[33,3502,3503,3505,3508],{"class":35,"line":269},[33,3504,3478],{"class":43},[33,3506,3507],{"class":39},"finally",[33,3509,1535],{"class":43},[33,3511,3512,3515,3517,3519],{"class":35,"line":279},[33,3513,3514],{"class":114},"      setSubmitting",[33,3516,149],{"class":43},[33,3518,3340],{"class":130},[33,3520,155],{"class":43},[33,3522,3523],{"class":35,"line":300},[33,3524,1555],{"class":43},[33,3526,3527],{"class":35,"line":305},[33,3528,348],{"class":43},[33,3530,3531],{"class":35,"line":321},[33,3532,58],{"emptyLinePlaceholder":57},[33,3534,3535,3537],{"class":35,"line":333},[33,3536,161],{"class":39},[33,3538,164],{"class":43},[33,3540,3541,3543,3545,3547,3549,3551,3553,3555],{"class":35,"line":345},[33,3542,170],{"class":43},[33,3544,368],{"class":173},[33,3546,371],{"class":114},[33,3548,143],{"class":39},[33,3550,1863],{"class":43},[33,3552,1866],{"class":114},[33,3554,143],{"class":39},[33,3556,1871],{"class":43},[33,3558,3559,3561,3563,3565,3567,3569,3571,3573,3575,3578],{"class":35,"line":351},[33,3560,382],{"class":43},[33,3562,385],{"class":173},[33,3564,1604],{"class":114},[33,3566,143],{"class":39},[33,3568,1609],{"class":50},[33,3570,388],{"class":114},[33,3572,143],{"class":39},[33,3574,393],{"class":50},[33,3576,3577],{"class":114}," required",[33,3579,1628],{"class":43},[33,3581,3582,3584,3586,3588,3590,3592,3594,3596,3598,3600],{"class":35,"line":356},[33,3583,382],{"class":43},[33,3585,385],{"class":173},[33,3587,1604],{"class":114},[33,3589,143],{"class":39},[33,3591,1641],{"class":50},[33,3593,388],{"class":114},[33,3595,143],{"class":39},[33,3597,1641],{"class":50},[33,3599,3577],{"class":114},[33,3601,1628],{"class":43},[33,3603,3604,3606,3608,3610,3612,3615,3617,3619,3621,3623],{"class":35,"line":363},[33,3605,382],{"class":43},[33,3607,385],{"class":173},[33,3609,1604],{"class":114},[33,3611,143],{"class":39},[33,3613,3614],{"class":50},"\"password\"",[33,3616,388],{"class":114},[33,3618,143],{"class":39},[33,3620,3614],{"class":50},[33,3622,3577],{"class":114},[33,3624,1628],{"class":43},[33,3626,3627],{"class":35,"line":379},[33,3628,58],{"emptyLinePlaceholder":57},[33,3630,3631,3633,3635,3638,3640,3642,3644,3646,3648,3650,3653,3655,3657,3660,3663,3665],{"class":35,"line":412},[33,3632,382],{"class":43},[33,3634,3146],{"class":173},[33,3636,3637],{"class":43},">\u003C",[33,3639,385],{"class":173},[33,3641,388],{"class":114},[33,3643,143],{"class":39},[33,3645,3161],{"class":50},[33,3647,1604],{"class":114},[33,3649,143],{"class":39},[33,3651,3652],{"class":50},"\"interests\"",[33,3654,555],{"class":114},[33,3656,143],{"class":39},[33,3658,3659],{"class":50},"\"sports\"",[33,3661,3662],{"class":43}," \u002F> Sports\u003C\u002F",[33,3664,3146],{"class":173},[33,3666,432],{"class":43},[33,3668,3669,3671,3673,3675,3677,3679,3681,3683,3685,3687,3689,3691,3693,3696,3699,3701],{"class":35,"line":435},[33,3670,382],{"class":43},[33,3672,3146],{"class":173},[33,3674,3637],{"class":43},[33,3676,385],{"class":173},[33,3678,388],{"class":114},[33,3680,143],{"class":39},[33,3682,3161],{"class":50},[33,3684,1604],{"class":114},[33,3686,143],{"class":39},[33,3688,3652],{"class":50},[33,3690,555],{"class":114},[33,3692,143],{"class":39},[33,3694,3695],{"class":50},"\"music\"",[33,3697,3698],{"class":43}," \u002F> Music\u003C\u002F",[33,3700,3146],{"class":173},[33,3702,432],{"class":43},[33,3704,3705,3707,3709,3711,3713,3715,3717,3719,3721,3723,3725,3727,3729,3732,3735,3737],{"class":35,"line":445},[33,3706,382],{"class":43},[33,3708,3146],{"class":173},[33,3710,3637],{"class":43},[33,3712,385],{"class":173},[33,3714,388],{"class":114},[33,3716,143],{"class":39},[33,3718,3161],{"class":50},[33,3720,1604],{"class":114},[33,3722,143],{"class":39},[33,3724,3652],{"class":50},[33,3726,555],{"class":114},[33,3728,143],{"class":39},[33,3730,3731],{"class":50},"\"reading\"",[33,3733,3734],{"class":43}," \u002F> Reading\u003C\u002F",[33,3736,3146],{"class":173},[33,3738,432],{"class":43},[33,3740,3741],{"class":35,"line":450},[33,3742,58],{"emptyLinePlaceholder":57},[33,3744,3745,3747,3749,3751,3753,3755,3758,3760],{"class":35,"line":1200},[33,3746,382],{"class":43},[33,3748,417],{"class":173},[33,3750,388],{"class":114},[33,3752,143],{"class":39},[33,3754,424],{"class":50},[33,3756,3757],{"class":114}," disabled",[33,3759,143],{"class":39},[33,3761,3762],{"class":43},"{submitting}>\n",[33,3764,3765,3768,3771,3774,3776,3779],{"class":35,"line":1227},[33,3766,3767],{"class":43},"        {submitting ",[33,3769,3770],{"class":39},"?",[33,3772,3773],{"class":50}," 'Creating account…'",[33,3775,1293],{"class":39},[33,3777,3778],{"class":50}," 'Sign Up'",[33,3780,238],{"class":43},[33,3782,3783,3786,3788],{"class":35,"line":1240},[33,3784,3785],{"class":43},"      \u003C\u002F",[33,3787,417],{"class":173},[33,3789,432],{"class":43},[33,3791,3792,3794,3796],{"class":35,"line":1270},[33,3793,438],{"class":43},[33,3795,368],{"class":173},[33,3797,432],{"class":43},[33,3799,3800],{"class":35,"line":1330},[33,3801,232],{"class":43},[33,3803,3804],{"class":35,"line":1339},[33,3805,238],{"class":43},[33,3807,3808],{"class":35,"line":1344},[33,3809,58],{"emptyLinePlaceholder":57},[33,3811,3812],{"class":35,"line":1396},[33,3813,3814],{"class":64},"\u002F\u002F Sending FormData directly as multipart\u002Fform-data (for file uploads)\n",[33,3816,3817,3819,3822],{"class":35,"line":1970},[33,3818,111],{"class":39},[33,3820,3821],{"class":114}," UploadWithFormData",[33,3823,118],{"class":43},[33,3825,3826,3828,3830,3832,3834,3836],{"class":35,"line":1979},[33,3827,3351],{"class":39},[33,3829,3354],{"class":39},[33,3831,311],{"class":114},[33,3833,149],{"class":43},[33,3835,211],{"class":210},[33,3837,318],{"class":43},[33,3839,3840,3842,3844],{"class":35,"line":1984},[33,3841,324],{"class":43},[33,3843,327],{"class":114},[33,3845,330],{"class":43},[33,3847,3848,3850,3852,3854,3856,3858],{"class":35,"line":2515},[33,3849,851],{"class":39},[33,3851,1801],{"class":130},[33,3853,287],{"class":39},[33,3855,1806],{"class":39},[33,3857,1809],{"class":114},[33,3859,1812],{"class":43},[33,3861,3862],{"class":35,"line":2528},[33,3863,3864],{"class":64},"    \u002F\u002F Don't set Content-Type — the browser sets it automatically with the\n",[33,3866,3867],{"class":35,"line":2537},[33,3868,3869],{"class":64},"    \u002F\u002F correct multipart boundary when you pass FormData to fetch.\n",[33,3871,3872,3874,3877,3879,3882,3885,3887,3890],{"class":35,"line":2555},[33,3873,851],{"class":39},[33,3875,3876],{"class":130}," res",[33,3878,287],{"class":39},[33,3880,3881],{"class":39}," await",[33,3883,3884],{"class":114}," fetch",[33,3886,149],{"class":43},[33,3888,3889],{"class":50},"'\u002Fapi\u002Fupload'",[33,3891,3892],{"class":43},", {\n",[33,3894,3895,3898,3901],{"class":35,"line":2596},[33,3896,3897],{"class":43},"      method: ",[33,3899,3900],{"class":50},"'POST'",[33,3902,3903],{"class":43},",\n",[33,3905,3906],{"class":35,"line":2605},[33,3907,3908],{"class":43},"      body: formData,\n",[33,3910,3911],{"class":35,"line":2610},[33,3912,3913],{"class":43},"    })\n",[33,3915,3916,3919,3922,3925],{"class":35,"line":2615},[33,3917,3918],{"class":39},"    return",[33,3920,3921],{"class":43}," res.",[33,3923,3924],{"class":114},"json",[33,3926,330],{"class":43},[33,3928,3929],{"class":35,"line":2622},[33,3930,348],{"class":43},[33,3932,3933],{"class":35,"line":2635},[33,3934,58],{"emptyLinePlaceholder":57},[33,3936,3937,3939],{"class":35,"line":2669},[33,3938,161],{"class":39},[33,3940,164],{"class":43},[33,3942,3943,3945,3947,3949,3951],{"class":35,"line":2688},[33,3944,170],{"class":43},[33,3946,368],{"class":173},[33,3948,371],{"class":114},[33,3950,143],{"class":39},[33,3952,376],{"class":43},[33,3954,3955,3957,3959,3961,3963,3966,3968,3970,3972,3974],{"class":35,"line":2697},[33,3956,382],{"class":43},[33,3958,385],{"class":173},[33,3960,1604],{"class":114},[33,3962,143],{"class":39},[33,3964,3965],{"class":50},"\"title\"",[33,3967,388],{"class":114},[33,3969,143],{"class":39},[33,3971,393],{"class":50},[33,3973,3577],{"class":114},[33,3975,1628],{"class":43},[33,3977,3978,3980,3982,3984,3986,3988,3990,3992,3994,3996],{"class":35,"line":2702},[33,3979,382],{"class":43},[33,3981,385],{"class":173},[33,3983,1604],{"class":114},[33,3985,143],{"class":39},[33,3987,2646],{"class":50},[33,3989,388],{"class":114},[33,3991,143],{"class":39},[33,3993,2646],{"class":50},[33,3995,3577],{"class":114},[33,3997,1628],{"class":43},[33,3999,4000,4002,4004,4006,4008,4010,4012,4014],{"class":35,"line":2707},[33,4001,382],{"class":43},[33,4003,417],{"class":173},[33,4005,388],{"class":114},[33,4007,143],{"class":39},[33,4009,424],{"class":50},[33,4011,2458],{"class":43},[33,4013,417],{"class":173},[33,4015,432],{"class":43},[33,4017,4018,4020,4022],{"class":35,"line":2712},[33,4019,438],{"class":43},[33,4021,368],{"class":173},[33,4023,432],{"class":43},[33,4025,4026],{"class":35,"line":2718},[33,4027,232],{"class":43},[33,4029,4030],{"class":35,"line":2728},[33,4031,238],{"class":43},[14,4033,4035],{"id":4034},"multi-field-form-with-usestate-object-state","Multi-Field Form with useState (Object State)",[19,4037,4039],{"filename":4038,"language":22},"multifield_usestate.js",[24,4040,4042],{"className":26,"code":4041,"language":22,"meta":28,"style":28},"import { useState } from 'react'\n\n\u002F\u002F One useState per field works for 2-3 fields. Beyond that, a single state object\n\u002F\u002F with a shared change handler scales better. The `name` attribute maps to state keys.\n\nfunction SignupForm() {\n  const [form, setForm] = useState({\n    name: '',\n    email: '',\n    password: '',\n    confirmPassword: '',\n  })\n\n  function handleChange(e) {\n    const { name, value, type, checked } = e.target\n    setForm(prev => ({\n      ...prev,\n      [name]: type === 'checkbox' ? checked : value,\n    }))\n  }\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    if (form.password !== form.confirmPassword) {\n      alert('Passwords do not match')\n      return\n    }\n    submitSignup(form)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit}>\n      \u003Cinput name=\"name\"      value={form.name}      onChange={handleChange} required \u002F>\n      \u003Cinput name=\"email\"     value={form.email}     onChange={handleChange} type=\"email\" required \u002F>\n      \u003Cinput name=\"password\"  value={form.password}  onChange={handleChange} type=\"password\" required \u002F>\n      \u003Cinput name=\"confirmPassword\" value={form.confirmPassword} onChange={handleChange} type=\"password\" required \u002F>\n      \u003Cbutton type=\"submit\">Sign Up\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n  \u002F\u002F The computed property name [name]: value makes one handler work for every field.\n  \u002F\u002F Trade-off: setForm replaces the entire object on every keystroke, re-rendering\n  \u002F\u002F all fields. For 5-15 fields, fine. For 50+ fields, consider uncontrolled.\n}\n",[30,4043,4044,4054,4058,4063,4068,4072,4081,4103,4112,4121,4130,4139,4144,4148,4160,4191,4206,4214,4235,4240,4244,4248,4260,4268,4281,4292,4296,4300,4308,4312,4316,4322,4334,4363,4399,4435,4471,4490,4498,4502,4507,4512,4517],{"__ignoreMap":28},[33,4045,4046,4048,4050,4052],{"class":35,"line":36},[33,4047,40],{"class":39},[33,4049,471],{"class":43},[33,4051,47],{"class":39},[33,4053,51],{"class":50},[33,4055,4056],{"class":35,"line":54},[33,4057,58],{"emptyLinePlaceholder":57},[33,4059,4060],{"class":35,"line":61},[33,4061,4062],{"class":64},"\u002F\u002F One useState per field works for 2-3 fields. Beyond that, a single state object\n",[33,4064,4065],{"class":35,"line":68},[33,4066,4067],{"class":64},"\u002F\u002F with a shared change handler scales better. The `name` attribute maps to state keys.\n",[33,4069,4070],{"class":35,"line":74},[33,4071,58],{"emptyLinePlaceholder":57},[33,4073,4074,4076,4079],{"class":35,"line":79},[33,4075,111],{"class":39},[33,4077,4078],{"class":114}," SignupForm",[33,4080,118],{"class":43},[33,4082,4083,4085,4087,4089,4091,4094,4096,4098,4100],{"class":35,"line":85},[33,4084,124],{"class":39},[33,4086,127],{"class":43},[33,4088,368],{"class":130},[33,4090,134],{"class":43},[33,4092,4093],{"class":130},"setForm",[33,4095,140],{"class":43},[33,4097,143],{"class":39},[33,4099,146],{"class":114},[33,4101,4102],{"class":43},"({\n",[33,4104,4105,4108,4110],{"class":35,"line":91},[33,4106,4107],{"class":43},"    name: ",[33,4109,152],{"class":50},[33,4111,3903],{"class":43},[33,4113,4114,4117,4119],{"class":35,"line":97},[33,4115,4116],{"class":43},"    email: ",[33,4118,152],{"class":50},[33,4120,3903],{"class":43},[33,4122,4123,4126,4128],{"class":35,"line":103},[33,4124,4125],{"class":43},"    password: ",[33,4127,152],{"class":50},[33,4129,3903],{"class":43},[33,4131,4132,4135,4137],{"class":35,"line":108},[33,4133,4134],{"class":43},"    confirmPassword: ",[33,4136,152],{"class":50},[33,4138,3903],{"class":43},[33,4140,4141],{"class":35,"line":121},[33,4142,4143],{"class":43},"  })\n",[33,4145,4146],{"class":35,"line":158},[33,4147,58],{"emptyLinePlaceholder":57},[33,4149,4150,4152,4154,4156,4158],{"class":35,"line":167},[33,4151,308],{"class":39},[33,4153,840],{"class":114},[33,4155,149],{"class":43},[33,4157,211],{"class":210},[33,4159,318],{"class":43},[33,4161,4162,4164,4167,4169,4171,4173,4175,4178,4180,4183,4186,4188],{"class":35,"line":177},[33,4163,851],{"class":39},[33,4165,4166],{"class":43}," { ",[33,4168,531],{"class":130},[33,4170,134],{"class":43},[33,4172,608],{"class":130},[33,4174,134],{"class":43},[33,4176,4177],{"class":130},"type",[33,4179,134],{"class":43},[33,4181,4182],{"class":130},"checked",[33,4184,4185],{"class":43}," } ",[33,4187,143],{"class":39},[33,4189,4190],{"class":43}," e.target\n",[33,4192,4193,4196,4198,4201,4203],{"class":35,"line":188},[33,4194,4195],{"class":114},"    setForm",[33,4197,149],{"class":43},[33,4199,4200],{"class":210},"prev",[33,4202,214],{"class":39},[33,4204,4205],{"class":43}," ({\n",[33,4207,4208,4211],{"class":35,"line":199},[33,4209,4210],{"class":39},"      ...",[33,4212,4213],{"class":43},"prev,\n",[33,4215,4216,4219,4221,4224,4226,4229,4232],{"class":35,"line":223},[33,4217,4218],{"class":43},"      [name]: type ",[33,4220,1283],{"class":39},[33,4222,4223],{"class":50}," 'checkbox'",[33,4225,1288],{"class":39},[33,4227,4228],{"class":43}," checked ",[33,4230,4231],{"class":39},":",[33,4233,4234],{"class":43}," value,\n",[33,4236,4237],{"class":35,"line":229},[33,4238,4239],{"class":43},"    }))\n",[33,4241,4242],{"class":35,"line":235},[33,4243,348],{"class":43},[33,4245,4246],{"class":35,"line":241},[33,4247,58],{"emptyLinePlaceholder":57},[33,4249,4250,4252,4254,4256,4258],{"class":35,"line":246},[33,4251,308],{"class":39},[33,4253,311],{"class":114},[33,4255,149],{"class":43},[33,4257,211],{"class":210},[33,4259,318],{"class":43},[33,4261,4262,4264,4266],{"class":35,"line":252},[33,4263,324],{"class":43},[33,4265,327],{"class":114},[33,4267,330],{"class":43},[33,4269,4270,4272,4275,4278],{"class":35,"line":258},[33,4271,2123],{"class":39},[33,4273,4274],{"class":43}," (form.password ",[33,4276,4277],{"class":39},"!==",[33,4279,4280],{"class":43}," form.confirmPassword) {\n",[33,4282,4283,4285,4287,4290],{"class":35,"line":264},[33,4284,2166],{"class":114},[33,4286,149],{"class":43},[33,4288,4289],{"class":50},"'Passwords do not match'",[33,4291,155],{"class":43},[33,4293,4294],{"class":35,"line":269},[33,4295,2188],{"class":39},[33,4297,4298],{"class":35,"line":279},[33,4299,1555],{"class":43},[33,4301,4302,4305],{"class":35,"line":300},[33,4303,4304],{"class":114},"    submitSignup",[33,4306,4307],{"class":43},"(form)\n",[33,4309,4310],{"class":35,"line":305},[33,4311,348],{"class":43},[33,4313,4314],{"class":35,"line":321},[33,4315,58],{"emptyLinePlaceholder":57},[33,4317,4318,4320],{"class":35,"line":333},[33,4319,161],{"class":39},[33,4321,164],{"class":43},[33,4323,4324,4326,4328,4330,4332],{"class":35,"line":345},[33,4325,170],{"class":43},[33,4327,368],{"class":173},[33,4329,371],{"class":114},[33,4331,143],{"class":39},[33,4333,376],{"class":43},[33,4335,4336,4338,4340,4342,4344,4346,4348,4350,4353,4355,4357,4359,4361],{"class":35,"line":351},[33,4337,382],{"class":43},[33,4339,385],{"class":173},[33,4341,1604],{"class":114},[33,4343,143],{"class":39},[33,4345,1609],{"class":50},[33,4347,191],{"class":114},[33,4349,143],{"class":39},[33,4351,4352],{"class":43},"{form.name}      ",[33,4354,643],{"class":114},[33,4356,143],{"class":39},[33,4358,1371],{"class":43},[33,4360,1625],{"class":114},[33,4362,1628],{"class":43},[33,4364,4365,4367,4369,4371,4373,4375,4378,4380,4383,4385,4387,4389,4391,4393,4395,4397],{"class":35,"line":356},[33,4366,382],{"class":43},[33,4368,385],{"class":173},[33,4370,1604],{"class":114},[33,4372,143],{"class":39},[33,4374,1641],{"class":50},[33,4376,4377],{"class":114},"     value",[33,4379,143],{"class":39},[33,4381,4382],{"class":43},"{form.email}     ",[33,4384,643],{"class":114},[33,4386,143],{"class":39},[33,4388,1371],{"class":43},[33,4390,4177],{"class":114},[33,4392,143],{"class":39},[33,4394,1641],{"class":50},[33,4396,3577],{"class":114},[33,4398,1628],{"class":43},[33,4400,4401,4403,4405,4407,4409,4411,4414,4416,4419,4421,4423,4425,4427,4429,4431,4433],{"class":35,"line":363},[33,4402,382],{"class":43},[33,4404,385],{"class":173},[33,4406,1604],{"class":114},[33,4408,143],{"class":39},[33,4410,3614],{"class":50},[33,4412,4413],{"class":114},"  value",[33,4415,143],{"class":39},[33,4417,4418],{"class":43},"{form.password}  ",[33,4420,643],{"class":114},[33,4422,143],{"class":39},[33,4424,1371],{"class":43},[33,4426,4177],{"class":114},[33,4428,143],{"class":39},[33,4430,3614],{"class":50},[33,4432,3577],{"class":114},[33,4434,1628],{"class":43},[33,4436,4437,4439,4441,4443,4445,4448,4450,4452,4455,4457,4459,4461,4463,4465,4467,4469],{"class":35,"line":379},[33,4438,382],{"class":43},[33,4440,385],{"class":173},[33,4442,1604],{"class":114},[33,4444,143],{"class":39},[33,4446,4447],{"class":50},"\"confirmPassword\"",[33,4449,555],{"class":114},[33,4451,143],{"class":39},[33,4453,4454],{"class":43},"{form.confirmPassword} ",[33,4456,643],{"class":114},[33,4458,143],{"class":39},[33,4460,1371],{"class":43},[33,4462,4177],{"class":114},[33,4464,143],{"class":39},[33,4466,3614],{"class":50},[33,4468,3577],{"class":114},[33,4470,1628],{"class":43},[33,4472,4473,4475,4477,4479,4481,4483,4486,4488],{"class":35,"line":412},[33,4474,382],{"class":43},[33,4476,417],{"class":173},[33,4478,388],{"class":114},[33,4480,143],{"class":39},[33,4482,424],{"class":50},[33,4484,4485],{"class":43},">Sign Up\u003C\u002F",[33,4487,417],{"class":173},[33,4489,432],{"class":43},[33,4491,4492,4494,4496],{"class":35,"line":435},[33,4493,438],{"class":43},[33,4495,368],{"class":173},[33,4497,432],{"class":43},[33,4499,4500],{"class":35,"line":445},[33,4501,232],{"class":43},[33,4503,4504],{"class":35,"line":450},[33,4505,4506],{"class":64},"  \u002F\u002F The computed property name [name]: value makes one handler work for every field.\n",[33,4508,4509],{"class":35,"line":1200},[33,4510,4511],{"class":64},"  \u002F\u002F Trade-off: setForm replaces the entire object on every keystroke, re-rendering\n",[33,4513,4514],{"class":35,"line":1227},[33,4515,4516],{"class":64},"  \u002F\u002F all fields. For 5-15 fields, fine. For 50+ fields, consider uncontrolled.\n",[33,4518,4519],{"class":35,"line":1240},[33,4520,238],{"class":43},[14,4522,4524],{"id":4523},"multi-field-form-with-usereducer-complex-state","Multi-Field Form with useReducer (Complex State)",[19,4526,4528],{"filename":4527,"language":22},"multifield_usereducer.js",[24,4529,4531],{"className":26,"code":4530,"language":22,"meta":28,"style":28},"import { useReducer, useCallback } from 'react'\n\n\u002F\u002F For forms with complex state transitions (validation, multi-step, dependent fields,\n\u002F\u002F async submit state), useReducer is more maintainable than multiple useState calls.\n\u002F\u002F See Ch 10 (useReducer) for the reducer fundamentals.\n\nconst initialState = {\n  values: { name: '', email: '', password: '', role: 'member' },\n  errors: {},\n  touched: {},\n  status: 'idle',  \u002F\u002F 'idle' | 'validating' | 'submitting' | 'success' | 'error'\n  submitError: null,\n}\n\nfunction formReducer(state, action) {\n  switch (action.type) {\n    case 'FIELD_CHANGE': {\n      const { name, value } = action\n      return {\n        ...state,\n        values: { ...state.values, [name]: value },\n        errors: { ...state.errors, [name]: undefined },\n      }\n    }\n    case 'FIELD_BLUR': {\n      const { name } = action\n      return {\n        ...state,\n        touched: { ...state.touched, [name]: true },\n        errors: { ...state.errors, [name]: action.error },\n      }\n    }\n    case 'VALIDATE':\n      return { ...state, errors: action.errors, status: 'idle' }\n    case 'SUBMIT_START':\n      return { ...state, status: 'submitting', submitError: null }\n    case 'SUBMIT_SUCCESS':\n      return { ...state, status: 'success' }\n    case 'SUBMIT_ERROR':\n      return { ...state, status: 'error', submitError: action.error }\n    case 'RESET':\n      return { ...initialState, values: { ...initialState.values } }\n    default:\n      return state\n  }\n}\n\nconst validators = {\n  name: (val) => val.length \u003C 2 ? 'Name must be at least 2 characters' : undefined,\n  email: (val) => !val.includes('@') ? 'Enter a valid email' : undefined,\n  password: (val) => val.length \u003C 8 ? 'Password must be at least 8 characters' : undefined,\n}\n\nfunction validateAll(values) {\n  const errors = {}\n  for (const [field, validate] of Object.entries(validators)) {\n    const error = validate(values[field])\n    if (error) errors[field] = error\n  }\n  return errors\n}\n\nfunction ComplexSignupForm({ onSubmit }) {\n  const [state, dispatch] = useReducer(formReducer, initialState)\n  const { values, errors, touched, status, submitError } = state\n\n  const handleChange = useCallback((e) => {\n    const { name, value } = e.target\n    dispatch({ type: 'FIELD_CHANGE', name, value })\n  }, [])\n\n  const handleBlur = useCallback((e) => {\n    const { name } = e.target\n    const error = validators[name]?.(values[name])\n    dispatch({ type: 'FIELD_BLUR', name, error })\n  }, [values])\n\n  const handleSubmit = useCallback(async (e) => {\n    e.preventDefault()\n    const allErrors = validateAll(values)\n    dispatch({ type: 'VALIDATE', errors: allErrors })\n    if (Object.keys(allErrors).length > 0) return\n\n    dispatch({ type: 'SUBMIT_START' })\n    try {\n      await onSubmit(values)\n      dispatch({ type: 'SUBMIT_SUCCESS' })\n    } catch (err) {\n      dispatch({ type: 'SUBMIT_ERROR', error: err.message })\n    }\n  }, [values, onSubmit])\n\n  return (\n    \u003Cform onSubmit={handleSubmit} noValidate>\n      \u003Cdiv>\n        \u003Cinput\n          name=\"name\"\n          value={values.name}\n          onChange={handleChange}\n          onBlur={handleBlur}\n          placeholder=\"Name\"\n        \u002F>\n        {touched.name && errors.name && \u003Cp className=\"error\">{errors.name}\u003C\u002Fp>}\n      \u003C\u002Fdiv>\n\n      \u003Cdiv>\n        \u003Cinput\n          name=\"email\"\n          type=\"email\"\n          value={values.email}\n          onChange={handleChange}\n          onBlur={handleBlur}\n          placeholder=\"Email\"\n        \u002F>\n        {touched.email && errors.email && \u003Cp className=\"error\">{errors.email}\u003C\u002Fp>}\n      \u003C\u002Fdiv>\n\n      \u003Cdiv>\n        \u003Cinput\n          name=\"password\"\n          type=\"password\"\n          value={values.password}\n          onChange={handleChange}\n          onBlur={handleBlur}\n          placeholder=\"Password\"\n        \u002F>\n        {touched.password && errors.password && \u003Cp className=\"error\">{errors.password}\u003C\u002Fp>}\n      \u003C\u002Fdiv>\n\n      \u003Cdiv>\n        \u003Cselect name=\"role\" value={values.role} onChange={handleChange}>\n          \u003Coption value=\"member\">Member\u003C\u002Foption>\n          \u003Coption value=\"admin\">Admin\u003C\u002Foption>\n        \u003C\u002Fselect>\n      \u003C\u002Fdiv>\n\n      \u003Cbutton type=\"submit\" disabled={status === 'submitting'}>\n        {status === 'submitting' ? 'Creating…' : 'Sign Up'}\n      \u003C\u002Fbutton>\n\n      {status === 'error' && \u003Cp className=\"error\">Signup failed: {submitError}\u003C\u002Fp>}\n      {status === 'success' && \u003Cp className=\"success\">Account created!\u003C\u002Fp>}\n    \u003C\u002Fform>\n  )\n  \u002F\u002F useReducer keeps all form state transitions in one testable reducer function.\n  \u002F\u002F The component stays declarative — dispatch actions, read state, render.\n}\n",[30,4532,4533,4544,4548,4553,4558,4563,4567,4579,4605,4610,4615,4629,4638,4642,4646,4665,4673,4684,4704,4711,4719,4730,4745,4750,4754,4763,4777,4783,4789,4803,4812,4816,4820,4830,4846,4855,4876,4885,4900,4909,4925,4934,4950,4957,4964,4968,4972,4976,4987,5025,5065,5098,5102,5106,5120,5132,5163,5178,5190,5194,5201,5205,5209,5223,5246,5280,5284,5306,5324,5338,5343,5347,5368,5382,5393,5405,5410,5414,5439,5447,5462,5475,5501,5506,5519,5526,5535,5548,5557,5570,5575,5581,5586,5593,5611,5621,5629,5640,5651,5661,5672,5683,5689,5723,5732,5737,5746,5753,5762,5772,5782,5791,5800,5810,5815,5845,5854,5859,5868,5875,5885,5894,5904,5913,5922,5932,5937,5967,5976,5981,5990,6019,6042,6063,6073,6082,6087,6115,6136,6145,6150,6181,6211,6220,6225,6231,6237],{"__ignoreMap":28},[33,4534,4535,4537,4540,4542],{"class":35,"line":36},[33,4536,40],{"class":39},[33,4538,4539],{"class":43}," { useReducer, useCallback } ",[33,4541,47],{"class":39},[33,4543,51],{"class":50},[33,4545,4546],{"class":35,"line":54},[33,4547,58],{"emptyLinePlaceholder":57},[33,4549,4550],{"class":35,"line":61},[33,4551,4552],{"class":64},"\u002F\u002F For forms with complex state transitions (validation, multi-step, dependent fields,\n",[33,4554,4555],{"class":35,"line":68},[33,4556,4557],{"class":64},"\u002F\u002F async submit state), useReducer is more maintainable than multiple useState calls.\n",[33,4559,4560],{"class":35,"line":74},[33,4561,4562],{"class":64},"\u002F\u002F See Ch 10 (useReducer) for the reducer fundamentals.\n",[33,4564,4565],{"class":35,"line":79},[33,4566,58],{"emptyLinePlaceholder":57},[33,4568,4569,4572,4575,4577],{"class":35,"line":85},[33,4570,4571],{"class":39},"const",[33,4573,4574],{"class":130}," initialState",[33,4576,287],{"class":39},[33,4578,1535],{"class":43},[33,4580,4581,4584,4586,4589,4591,4594,4596,4599,4602],{"class":35,"line":91},[33,4582,4583],{"class":43},"  values: { name: ",[33,4585,152],{"class":50},[33,4587,4588],{"class":43},", email: ",[33,4590,152],{"class":50},[33,4592,4593],{"class":43},", password: ",[33,4595,152],{"class":50},[33,4597,4598],{"class":43},", role: ",[33,4600,4601],{"class":50},"'member'",[33,4603,4604],{"class":43}," },\n",[33,4606,4607],{"class":35,"line":97},[33,4608,4609],{"class":43},"  errors: {},\n",[33,4611,4612],{"class":35,"line":103},[33,4613,4614],{"class":43},"  touched: {},\n",[33,4616,4617,4620,4623,4626],{"class":35,"line":108},[33,4618,4619],{"class":43},"  status: ",[33,4621,4622],{"class":50},"'idle'",[33,4624,4625],{"class":43},",  ",[33,4627,4628],{"class":64},"\u002F\u002F 'idle' | 'validating' | 'submitting' | 'success' | 'error'\n",[33,4630,4631,4634,4636],{"class":35,"line":121},[33,4632,4633],{"class":43},"  submitError: ",[33,4635,295],{"class":130},[33,4637,3903],{"class":43},[33,4639,4640],{"class":35,"line":158},[33,4641,238],{"class":43},[33,4643,4644],{"class":35,"line":167},[33,4645,58],{"emptyLinePlaceholder":57},[33,4647,4648,4650,4653,4655,4658,4660,4663],{"class":35,"line":177},[33,4649,111],{"class":39},[33,4651,4652],{"class":114}," formReducer",[33,4654,149],{"class":43},[33,4656,4657],{"class":210},"state",[33,4659,134],{"class":43},[33,4661,4662],{"class":210},"action",[33,4664,318],{"class":43},[33,4666,4667,4670],{"class":35,"line":188},[33,4668,4669],{"class":39},"  switch",[33,4671,4672],{"class":43}," (action.type) {\n",[33,4674,4675,4678,4681],{"class":35,"line":199},[33,4676,4677],{"class":39},"    case",[33,4679,4680],{"class":50}," 'FIELD_CHANGE'",[33,4682,4683],{"class":43},": {\n",[33,4685,4686,4689,4691,4693,4695,4697,4699,4701],{"class":35,"line":223},[33,4687,4688],{"class":39},"      const",[33,4690,4166],{"class":43},[33,4692,531],{"class":130},[33,4694,134],{"class":43},[33,4696,608],{"class":130},[33,4698,4185],{"class":43},[33,4700,143],{"class":39},[33,4702,4703],{"class":43}," action\n",[33,4705,4706,4709],{"class":35,"line":229},[33,4707,4708],{"class":39},"      return",[33,4710,1535],{"class":43},[33,4712,4713,4716],{"class":35,"line":235},[33,4714,4715],{"class":39},"        ...",[33,4717,4718],{"class":43},"state,\n",[33,4720,4721,4724,4727],{"class":35,"line":241},[33,4722,4723],{"class":43},"        values: { ",[33,4725,4726],{"class":39},"...",[33,4728,4729],{"class":43},"state.values, [name]: value },\n",[33,4731,4732,4735,4737,4740,4743],{"class":35,"line":246},[33,4733,4734],{"class":43},"        errors: { ",[33,4736,4726],{"class":39},[33,4738,4739],{"class":43},"state.errors, [name]: ",[33,4741,4742],{"class":130},"undefined",[33,4744,4604],{"class":43},[33,4746,4747],{"class":35,"line":252},[33,4748,4749],{"class":43},"      }\n",[33,4751,4752],{"class":35,"line":258},[33,4753,1555],{"class":43},[33,4755,4756,4758,4761],{"class":35,"line":264},[33,4757,4677],{"class":39},[33,4759,4760],{"class":50}," 'FIELD_BLUR'",[33,4762,4683],{"class":43},[33,4764,4765,4767,4769,4771,4773,4775],{"class":35,"line":269},[33,4766,4688],{"class":39},[33,4768,4166],{"class":43},[33,4770,531],{"class":130},[33,4772,4185],{"class":43},[33,4774,143],{"class":39},[33,4776,4703],{"class":43},[33,4778,4779,4781],{"class":35,"line":279},[33,4780,4708],{"class":39},[33,4782,1535],{"class":43},[33,4784,4785,4787],{"class":35,"line":300},[33,4786,4715],{"class":39},[33,4788,4718],{"class":43},[33,4790,4791,4794,4796,4799,4801],{"class":35,"line":305},[33,4792,4793],{"class":43},"        touched: { ",[33,4795,4726],{"class":39},[33,4797,4798],{"class":43},"state.touched, [name]: ",[33,4800,3171],{"class":130},[33,4802,4604],{"class":43},[33,4804,4805,4807,4809],{"class":35,"line":321},[33,4806,4734],{"class":43},[33,4808,4726],{"class":39},[33,4810,4811],{"class":43},"state.errors, [name]: action.error },\n",[33,4813,4814],{"class":35,"line":333},[33,4815,4749],{"class":43},[33,4817,4818],{"class":35,"line":345},[33,4819,1555],{"class":43},[33,4821,4822,4824,4827],{"class":35,"line":351},[33,4823,4677],{"class":39},[33,4825,4826],{"class":50}," 'VALIDATE'",[33,4828,4829],{"class":43},":\n",[33,4831,4832,4834,4836,4838,4841,4843],{"class":35,"line":356},[33,4833,4708],{"class":39},[33,4835,4166],{"class":43},[33,4837,4726],{"class":39},[33,4839,4840],{"class":43},"state, errors: action.errors, status: ",[33,4842,4622],{"class":50},[33,4844,4845],{"class":43}," }\n",[33,4847,4848,4850,4853],{"class":35,"line":363},[33,4849,4677],{"class":39},[33,4851,4852],{"class":50}," 'SUBMIT_START'",[33,4854,4829],{"class":43},[33,4856,4857,4859,4861,4863,4866,4869,4872,4874],{"class":35,"line":379},[33,4858,4708],{"class":39},[33,4860,4166],{"class":43},[33,4862,4726],{"class":39},[33,4864,4865],{"class":43},"state, status: ",[33,4867,4868],{"class":50},"'submitting'",[33,4870,4871],{"class":43},", submitError: ",[33,4873,295],{"class":130},[33,4875,4845],{"class":43},[33,4877,4878,4880,4883],{"class":35,"line":412},[33,4879,4677],{"class":39},[33,4881,4882],{"class":50}," 'SUBMIT_SUCCESS'",[33,4884,4829],{"class":43},[33,4886,4887,4889,4891,4893,4895,4898],{"class":35,"line":435},[33,4888,4708],{"class":39},[33,4890,4166],{"class":43},[33,4892,4726],{"class":39},[33,4894,4865],{"class":43},[33,4896,4897],{"class":50},"'success'",[33,4899,4845],{"class":43},[33,4901,4902,4904,4907],{"class":35,"line":445},[33,4903,4677],{"class":39},[33,4905,4906],{"class":50}," 'SUBMIT_ERROR'",[33,4908,4829],{"class":43},[33,4910,4911,4913,4915,4917,4919,4922],{"class":35,"line":450},[33,4912,4708],{"class":39},[33,4914,4166],{"class":43},[33,4916,4726],{"class":39},[33,4918,4865],{"class":43},[33,4920,4921],{"class":50},"'error'",[33,4923,4924],{"class":43},", submitError: action.error }\n",[33,4926,4927,4929,4932],{"class":35,"line":1200},[33,4928,4677],{"class":39},[33,4930,4931],{"class":50}," 'RESET'",[33,4933,4829],{"class":43},[33,4935,4936,4938,4940,4942,4945,4947],{"class":35,"line":1227},[33,4937,4708],{"class":39},[33,4939,4166],{"class":43},[33,4941,4726],{"class":39},[33,4943,4944],{"class":43},"initialState, values: { ",[33,4946,4726],{"class":39},[33,4948,4949],{"class":43},"initialState.values } }\n",[33,4951,4952,4955],{"class":35,"line":1240},[33,4953,4954],{"class":39},"    default",[33,4956,4829],{"class":43},[33,4958,4959,4961],{"class":35,"line":1270},[33,4960,4708],{"class":39},[33,4962,4963],{"class":43}," state\n",[33,4965,4966],{"class":35,"line":1330},[33,4967,348],{"class":43},[33,4969,4970],{"class":35,"line":1339},[33,4971,238],{"class":43},[33,4973,4974],{"class":35,"line":1344},[33,4975,58],{"emptyLinePlaceholder":57},[33,4977,4978,4980,4983,4985],{"class":35,"line":1396},[33,4979,4571],{"class":39},[33,4981,4982],{"class":130}," validators",[33,4984,287],{"class":39},[33,4986,1535],{"class":43},[33,4988,4989,4992,4995,4998,5000,5002,5005,5008,5010,5013,5015,5018,5020,5023],{"class":35,"line":1970},[33,4990,4991],{"class":114},"  name",[33,4993,4994],{"class":43},": (",[33,4996,4997],{"class":210},"val",[33,4999,984],{"class":43},[33,5001,1955],{"class":39},[33,5003,5004],{"class":43}," val.",[33,5006,5007],{"class":130},"length",[33,5009,550],{"class":39},[33,5011,5012],{"class":130}," 2",[33,5014,1288],{"class":39},[33,5016,5017],{"class":50}," 'Name must be at least 2 characters'",[33,5019,1293],{"class":39},[33,5021,5022],{"class":130}," undefined",[33,5024,3903],{"class":43},[33,5026,5027,5030,5032,5034,5036,5038,5041,5044,5047,5049,5052,5054,5056,5059,5061,5063],{"class":35,"line":1979},[33,5028,5029],{"class":114},"  email",[33,5031,4994],{"class":43},[33,5033,4997],{"class":210},[33,5035,984],{"class":43},[33,5037,1955],{"class":39},[33,5039,5040],{"class":39}," !",[33,5042,5043],{"class":43},"val.",[33,5045,5046],{"class":114},"includes",[33,5048,149],{"class":43},[33,5050,5051],{"class":50},"'@'",[33,5053,984],{"class":43},[33,5055,3770],{"class":39},[33,5057,5058],{"class":50}," 'Enter a valid email'",[33,5060,1293],{"class":39},[33,5062,5022],{"class":130},[33,5064,3903],{"class":43},[33,5066,5067,5070,5072,5074,5076,5078,5080,5082,5084,5087,5089,5092,5094,5096],{"class":35,"line":1984},[33,5068,5069],{"class":114},"  password",[33,5071,4994],{"class":43},[33,5073,4997],{"class":210},[33,5075,984],{"class":43},[33,5077,1955],{"class":39},[33,5079,5004],{"class":43},[33,5081,5007],{"class":130},[33,5083,550],{"class":39},[33,5085,5086],{"class":130}," 8",[33,5088,1288],{"class":39},[33,5090,5091],{"class":50}," 'Password must be at least 8 characters'",[33,5093,1293],{"class":39},[33,5095,5022],{"class":130},[33,5097,3903],{"class":43},[33,5099,5100],{"class":35,"line":2515},[33,5101,238],{"class":43},[33,5103,5104],{"class":35,"line":2528},[33,5105,58],{"emptyLinePlaceholder":57},[33,5107,5108,5110,5113,5115,5118],{"class":35,"line":2537},[33,5109,111],{"class":39},[33,5111,5112],{"class":114}," validateAll",[33,5114,149],{"class":43},[33,5116,5117],{"class":210},"values",[33,5119,318],{"class":43},[33,5121,5122,5124,5127,5129],{"class":35,"line":2555},[33,5123,124],{"class":39},[33,5125,5126],{"class":130}," errors",[33,5128,287],{"class":39},[33,5130,5131],{"class":43}," {}\n",[33,5133,5134,5137,5139,5141,5143,5146,5148,5151,5153,5156,5158,5160],{"class":35,"line":2596},[33,5135,5136],{"class":39},"  for",[33,5138,2126],{"class":43},[33,5140,4571],{"class":39},[33,5142,127],{"class":43},[33,5144,5145],{"class":130},"field",[33,5147,134],{"class":43},[33,5149,5150],{"class":130},"validate",[33,5152,140],{"class":43},[33,5154,5155],{"class":39},"of",[33,5157,3399],{"class":43},[33,5159,3407],{"class":114},[33,5161,5162],{"class":43},"(validators)) {\n",[33,5164,5165,5167,5170,5172,5175],{"class":35,"line":2605},[33,5166,851],{"class":39},[33,5168,5169],{"class":130}," error",[33,5171,287],{"class":39},[33,5173,5174],{"class":114}," validate",[33,5176,5177],{"class":43},"(values[field])\n",[33,5179,5180,5182,5185,5187],{"class":35,"line":2610},[33,5181,2123],{"class":39},[33,5183,5184],{"class":43}," (error) errors[field] ",[33,5186,143],{"class":39},[33,5188,5189],{"class":43}," error\n",[33,5191,5192],{"class":35,"line":2615},[33,5193,348],{"class":43},[33,5195,5196,5198],{"class":35,"line":2622},[33,5197,161],{"class":39},[33,5199,5200],{"class":43}," errors\n",[33,5202,5203],{"class":35,"line":2635},[33,5204,238],{"class":43},[33,5206,5207],{"class":35,"line":2669},[33,5208,58],{"emptyLinePlaceholder":57},[33,5210,5211,5213,5216,5218,5221],{"class":35,"line":2688},[33,5212,111],{"class":39},[33,5214,5215],{"class":114}," ComplexSignupForm",[33,5217,593],{"class":43},[33,5219,5220],{"class":210},"onSubmit",[33,5222,599],{"class":43},[33,5224,5225,5227,5229,5231,5233,5236,5238,5240,5243],{"class":35,"line":2697},[33,5226,124],{"class":39},[33,5228,127],{"class":43},[33,5230,4657],{"class":130},[33,5232,134],{"class":43},[33,5234,5235],{"class":130},"dispatch",[33,5237,140],{"class":43},[33,5239,143],{"class":39},[33,5241,5242],{"class":114}," useReducer",[33,5244,5245],{"class":43},"(formReducer, initialState)\n",[33,5247,5248,5250,5252,5254,5256,5259,5261,5264,5266,5269,5271,5274,5276,5278],{"class":35,"line":2702},[33,5249,124],{"class":39},[33,5251,4166],{"class":43},[33,5253,5117],{"class":130},[33,5255,134],{"class":43},[33,5257,5258],{"class":130},"errors",[33,5260,134],{"class":43},[33,5262,5263],{"class":130},"touched",[33,5265,134],{"class":43},[33,5267,5268],{"class":130},"status",[33,5270,134],{"class":43},[33,5272,5273],{"class":130},"submitError",[33,5275,4185],{"class":43},[33,5277,143],{"class":39},[33,5279,4963],{"class":43},[33,5281,5282],{"class":35,"line":2707},[33,5283,58],{"emptyLinePlaceholder":57},[33,5285,5286,5288,5290,5292,5295,5298,5300,5302,5304],{"class":35,"line":2712},[33,5287,124],{"class":39},[33,5289,840],{"class":130},[33,5291,287],{"class":39},[33,5293,5294],{"class":114}," useCallback",[33,5296,5297],{"class":43},"((",[33,5299,211],{"class":210},[33,5301,984],{"class":43},[33,5303,1955],{"class":39},[33,5305,1535],{"class":43},[33,5307,5308,5310,5312,5314,5316,5318,5320,5322],{"class":35,"line":2718},[33,5309,851],{"class":39},[33,5311,4166],{"class":43},[33,5313,531],{"class":130},[33,5315,134],{"class":43},[33,5317,608],{"class":130},[33,5319,4185],{"class":43},[33,5321,143],{"class":39},[33,5323,4190],{"class":43},[33,5325,5326,5329,5332,5335],{"class":35,"line":2728},[33,5327,5328],{"class":114},"    dispatch",[33,5330,5331],{"class":43},"({ type: ",[33,5333,5334],{"class":50},"'FIELD_CHANGE'",[33,5336,5337],{"class":43},", name, value })\n",[33,5339,5340],{"class":35,"line":2755},[33,5341,5342],{"class":43},"  }, [])\n",[33,5344,5345],{"class":35,"line":2762},[33,5346,58],{"emptyLinePlaceholder":57},[33,5348,5349,5351,5354,5356,5358,5360,5362,5364,5366],{"class":35,"line":2769},[33,5350,124],{"class":39},[33,5352,5353],{"class":130}," handleBlur",[33,5355,287],{"class":39},[33,5357,5294],{"class":114},[33,5359,5297],{"class":43},[33,5361,211],{"class":210},[33,5363,984],{"class":43},[33,5365,1955],{"class":39},[33,5367,1535],{"class":43},[33,5369,5370,5372,5374,5376,5378,5380],{"class":35,"line":2778},[33,5371,851],{"class":39},[33,5373,4166],{"class":43},[33,5375,531],{"class":130},[33,5377,4185],{"class":43},[33,5379,143],{"class":39},[33,5381,4190],{"class":43},[33,5383,5384,5386,5388,5390],{"class":35,"line":2788},[33,5385,851],{"class":39},[33,5387,5169],{"class":130},[33,5389,287],{"class":39},[33,5391,5392],{"class":43}," validators[name]?.(values[name])\n",[33,5394,5395,5397,5399,5402],{"class":35,"line":2806},[33,5396,5328],{"class":114},[33,5398,5331],{"class":43},[33,5400,5401],{"class":50},"'FIELD_BLUR'",[33,5403,5404],{"class":43},", name, error })\n",[33,5406,5407],{"class":35,"line":2811},[33,5408,5409],{"class":43},"  }, [values])\n",[33,5411,5412],{"class":35,"line":2816},[33,5413,58],{"emptyLinePlaceholder":57},[33,5415,5416,5418,5420,5422,5424,5426,5429,5431,5433,5435,5437],{"class":35,"line":2822},[33,5417,124],{"class":39},[33,5419,311],{"class":130},[33,5421,287],{"class":39},[33,5423,5294],{"class":114},[33,5425,149],{"class":43},[33,5427,5428],{"class":39},"async",[33,5430,2126],{"class":43},[33,5432,211],{"class":210},[33,5434,984],{"class":43},[33,5436,1955],{"class":39},[33,5438,1535],{"class":43},[33,5440,5441,5443,5445],{"class":35,"line":2828},[33,5442,324],{"class":43},[33,5444,327],{"class":114},[33,5446,330],{"class":43},[33,5448,5450,5452,5455,5457,5459],{"class":35,"line":5449},80,[33,5451,851],{"class":39},[33,5453,5454],{"class":130}," allErrors",[33,5456,287],{"class":39},[33,5458,5112],{"class":114},[33,5460,5461],{"class":43},"(values)\n",[33,5463,5465,5467,5469,5472],{"class":35,"line":5464},81,[33,5466,5328],{"class":114},[33,5468,5331],{"class":43},[33,5470,5471],{"class":50},"'VALIDATE'",[33,5473,5474],{"class":43},", errors: allErrors })\n",[33,5476,5478,5480,5483,5486,5489,5491,5494,5497,5499],{"class":35,"line":5477},82,[33,5479,2123],{"class":39},[33,5481,5482],{"class":43}," (Object.",[33,5484,5485],{"class":114},"keys",[33,5487,5488],{"class":43},"(allErrors).",[33,5490,5007],{"class":130},[33,5492,5493],{"class":39}," >",[33,5495,5496],{"class":130}," 0",[33,5498,984],{"class":43},[33,5500,2135],{"class":39},[33,5502,5504],{"class":35,"line":5503},83,[33,5505,58],{"emptyLinePlaceholder":57},[33,5507,5509,5511,5513,5516],{"class":35,"line":5508},84,[33,5510,5328],{"class":114},[33,5512,5331],{"class":43},[33,5514,5515],{"class":50},"'SUBMIT_START'",[33,5517,5518],{"class":43}," })\n",[33,5520,5522,5524],{"class":35,"line":5521},85,[33,5523,3449],{"class":39},[33,5525,1535],{"class":43},[33,5527,5529,5531,5533],{"class":35,"line":5528},86,[33,5530,3456],{"class":39},[33,5532,371],{"class":114},[33,5534,5461],{"class":43},[33,5536,5538,5541,5543,5546],{"class":35,"line":5537},87,[33,5539,5540],{"class":114},"      dispatch",[33,5542,5331],{"class":43},[33,5544,5545],{"class":50},"'SUBMIT_SUCCESS'",[33,5547,5518],{"class":43},[33,5549,5551,5553,5555],{"class":35,"line":5550},88,[33,5552,3478],{"class":43},[33,5554,3481],{"class":39},[33,5556,3484],{"class":43},[33,5558,5560,5562,5564,5567],{"class":35,"line":5559},89,[33,5561,5540],{"class":114},[33,5563,5331],{"class":43},[33,5565,5566],{"class":50},"'SUBMIT_ERROR'",[33,5568,5569],{"class":43},", error: err.message })\n",[33,5571,5573],{"class":35,"line":5572},90,[33,5574,1555],{"class":43},[33,5576,5578],{"class":35,"line":5577},91,[33,5579,5580],{"class":43},"  }, [values, onSubmit])\n",[33,5582,5584],{"class":35,"line":5583},92,[33,5585,58],{"emptyLinePlaceholder":57},[33,5587,5589,5591],{"class":35,"line":5588},93,[33,5590,161],{"class":39},[33,5592,164],{"class":43},[33,5594,5596,5598,5600,5602,5604,5606,5609],{"class":35,"line":5595},94,[33,5597,170],{"class":43},[33,5599,368],{"class":173},[33,5601,371],{"class":114},[33,5603,143],{"class":39},[33,5605,1863],{"class":43},[33,5607,5608],{"class":114},"noValidate",[33,5610,432],{"class":43},[33,5612,5614,5616,5619],{"class":35,"line":5613},95,[33,5615,382],{"class":43},[33,5617,5618],{"class":173},"div",[33,5620,432],{"class":43},[33,5622,5624,5627],{"class":35,"line":5623},96,[33,5625,5626],{"class":43},"        \u003C",[33,5628,174],{"class":173},[33,5630,5632,5635,5637],{"class":35,"line":5631},97,[33,5633,5634],{"class":114},"          name",[33,5636,143],{"class":39},[33,5638,5639],{"class":50},"\"name\"\n",[33,5641,5643,5646,5648],{"class":35,"line":5642},98,[33,5644,5645],{"class":114},"          value",[33,5647,143],{"class":39},[33,5649,5650],{"class":43},"{values.name}\n",[33,5652,5654,5657,5659],{"class":35,"line":5653},99,[33,5655,5656],{"class":114},"          onChange",[33,5658,143],{"class":39},[33,5660,1055],{"class":43},[33,5662,5664,5667,5669],{"class":35,"line":5663},100,[33,5665,5666],{"class":114},"          onBlur",[33,5668,143],{"class":39},[33,5670,5671],{"class":43},"{handleBlur}\n",[33,5673,5675,5678,5680],{"class":35,"line":5674},101,[33,5676,5677],{"class":114},"          placeholder",[33,5679,143],{"class":39},[33,5681,5682],{"class":50},"\"Name\"\n",[33,5684,5686],{"class":35,"line":5685},102,[33,5687,5688],{"class":43},"        \u002F>\n",[33,5690,5692,5695,5697,5700,5702,5704,5707,5710,5712,5715,5718,5720],{"class":35,"line":5691},103,[33,5693,5694],{"class":43},"        {touched.name ",[33,5696,2408],{"class":39},[33,5698,5699],{"class":43}," errors.name ",[33,5701,2408],{"class":39},[33,5703,550],{"class":43},[33,5705,5706],{"class":173},"p",[33,5708,5709],{"class":114}," className",[33,5711,143],{"class":39},[33,5713,5714],{"class":50},"\"error\"",[33,5716,5717],{"class":43},">{errors.name}\u003C\u002F",[33,5719,5706],{"class":173},[33,5721,5722],{"class":43},">}\n",[33,5724,5726,5728,5730],{"class":35,"line":5725},104,[33,5727,3785],{"class":43},[33,5729,5618],{"class":173},[33,5731,432],{"class":43},[33,5733,5735],{"class":35,"line":5734},105,[33,5736,58],{"emptyLinePlaceholder":57},[33,5738,5740,5742,5744],{"class":35,"line":5739},106,[33,5741,382],{"class":43},[33,5743,5618],{"class":173},[33,5745,432],{"class":43},[33,5747,5749,5751],{"class":35,"line":5748},107,[33,5750,5626],{"class":43},[33,5752,174],{"class":173},[33,5754,5756,5758,5760],{"class":35,"line":5755},108,[33,5757,5634],{"class":114},[33,5759,143],{"class":39},[33,5761,185],{"class":50},[33,5763,5765,5768,5770],{"class":35,"line":5764},109,[33,5766,5767],{"class":114},"          type",[33,5769,143],{"class":39},[33,5771,185],{"class":50},[33,5773,5775,5777,5779],{"class":35,"line":5774},110,[33,5776,5645],{"class":114},[33,5778,143],{"class":39},[33,5780,5781],{"class":43},"{values.email}\n",[33,5783,5785,5787,5789],{"class":35,"line":5784},111,[33,5786,5656],{"class":114},[33,5788,143],{"class":39},[33,5790,1055],{"class":43},[33,5792,5794,5796,5798],{"class":35,"line":5793},112,[33,5795,5666],{"class":114},[33,5797,143],{"class":39},[33,5799,5671],{"class":43},[33,5801,5803,5805,5807],{"class":35,"line":5802},113,[33,5804,5677],{"class":114},[33,5806,143],{"class":39},[33,5808,5809],{"class":50},"\"Email\"\n",[33,5811,5813],{"class":35,"line":5812},114,[33,5814,5688],{"class":43},[33,5816,5818,5821,5823,5826,5828,5830,5832,5834,5836,5838,5841,5843],{"class":35,"line":5817},115,[33,5819,5820],{"class":43},"        {touched.email ",[33,5822,2408],{"class":39},[33,5824,5825],{"class":43}," errors.email ",[33,5827,2408],{"class":39},[33,5829,550],{"class":43},[33,5831,5706],{"class":173},[33,5833,5709],{"class":114},[33,5835,143],{"class":39},[33,5837,5714],{"class":50},[33,5839,5840],{"class":43},">{errors.email}\u003C\u002F",[33,5842,5706],{"class":173},[33,5844,5722],{"class":43},[33,5846,5848,5850,5852],{"class":35,"line":5847},116,[33,5849,3785],{"class":43},[33,5851,5618],{"class":173},[33,5853,432],{"class":43},[33,5855,5857],{"class":35,"line":5856},117,[33,5858,58],{"emptyLinePlaceholder":57},[33,5860,5862,5864,5866],{"class":35,"line":5861},118,[33,5863,382],{"class":43},[33,5865,5618],{"class":173},[33,5867,432],{"class":43},[33,5869,5871,5873],{"class":35,"line":5870},119,[33,5872,5626],{"class":43},[33,5874,174],{"class":173},[33,5876,5878,5880,5882],{"class":35,"line":5877},120,[33,5879,5634],{"class":114},[33,5881,143],{"class":39},[33,5883,5884],{"class":50},"\"password\"\n",[33,5886,5888,5890,5892],{"class":35,"line":5887},121,[33,5889,5767],{"class":114},[33,5891,143],{"class":39},[33,5893,5884],{"class":50},[33,5895,5897,5899,5901],{"class":35,"line":5896},122,[33,5898,5645],{"class":114},[33,5900,143],{"class":39},[33,5902,5903],{"class":43},"{values.password}\n",[33,5905,5907,5909,5911],{"class":35,"line":5906},123,[33,5908,5656],{"class":114},[33,5910,143],{"class":39},[33,5912,1055],{"class":43},[33,5914,5916,5918,5920],{"class":35,"line":5915},124,[33,5917,5666],{"class":114},[33,5919,143],{"class":39},[33,5921,5671],{"class":43},[33,5923,5925,5927,5929],{"class":35,"line":5924},125,[33,5926,5677],{"class":114},[33,5928,143],{"class":39},[33,5930,5931],{"class":50},"\"Password\"\n",[33,5933,5935],{"class":35,"line":5934},126,[33,5936,5688],{"class":43},[33,5938,5940,5943,5945,5948,5950,5952,5954,5956,5958,5960,5963,5965],{"class":35,"line":5939},127,[33,5941,5942],{"class":43},"        {touched.password ",[33,5944,2408],{"class":39},[33,5946,5947],{"class":43}," errors.password ",[33,5949,2408],{"class":39},[33,5951,550],{"class":43},[33,5953,5706],{"class":173},[33,5955,5709],{"class":114},[33,5957,143],{"class":39},[33,5959,5714],{"class":50},[33,5961,5962],{"class":43},">{errors.password}\u003C\u002F",[33,5964,5706],{"class":173},[33,5966,5722],{"class":43},[33,5968,5970,5972,5974],{"class":35,"line":5969},128,[33,5971,3785],{"class":43},[33,5973,5618],{"class":173},[33,5975,432],{"class":43},[33,5977,5979],{"class":35,"line":5978},129,[33,5980,58],{"emptyLinePlaceholder":57},[33,5982,5984,5986,5988],{"class":35,"line":5983},130,[33,5985,382],{"class":43},[33,5987,5618],{"class":173},[33,5989,432],{"class":43},[33,5991,5993,5995,5998,6000,6002,6005,6007,6009,6012,6014,6016],{"class":35,"line":5992},131,[33,5994,5626],{"class":43},[33,5996,5997],{"class":173},"select",[33,5999,1604],{"class":114},[33,6001,143],{"class":39},[33,6003,6004],{"class":50},"\"role\"",[33,6006,555],{"class":114},[33,6008,143],{"class":39},[33,6010,6011],{"class":43},"{values.role} ",[33,6013,643],{"class":114},[33,6015,143],{"class":39},[33,6017,6018],{"class":43},"{handleChange}>\n",[33,6020,6022,6025,6028,6030,6032,6035,6038,6040],{"class":35,"line":6021},132,[33,6023,6024],{"class":43},"          \u003C",[33,6026,6027],{"class":173},"option",[33,6029,555],{"class":114},[33,6031,143],{"class":39},[33,6033,6034],{"class":50},"\"member\"",[33,6036,6037],{"class":43},">Member\u003C\u002F",[33,6039,6027],{"class":173},[33,6041,432],{"class":43},[33,6043,6045,6047,6049,6051,6053,6056,6059,6061],{"class":35,"line":6044},133,[33,6046,6024],{"class":43},[33,6048,6027],{"class":173},[33,6050,555],{"class":114},[33,6052,143],{"class":39},[33,6054,6055],{"class":50},"\"admin\"",[33,6057,6058],{"class":43},">Admin\u003C\u002F",[33,6060,6027],{"class":173},[33,6062,432],{"class":43},[33,6064,6066,6069,6071],{"class":35,"line":6065},134,[33,6067,6068],{"class":43},"        \u003C\u002F",[33,6070,5997],{"class":173},[33,6072,432],{"class":43},[33,6074,6076,6078,6080],{"class":35,"line":6075},135,[33,6077,3785],{"class":43},[33,6079,5618],{"class":173},[33,6081,432],{"class":43},[33,6083,6085],{"class":35,"line":6084},136,[33,6086,58],{"emptyLinePlaceholder":57},[33,6088,6090,6092,6094,6096,6098,6100,6102,6104,6107,6109,6112],{"class":35,"line":6089},137,[33,6091,382],{"class":43},[33,6093,417],{"class":173},[33,6095,388],{"class":114},[33,6097,143],{"class":39},[33,6099,424],{"class":50},[33,6101,3757],{"class":114},[33,6103,143],{"class":39},[33,6105,6106],{"class":43},"{status ",[33,6108,1283],{"class":39},[33,6110,6111],{"class":50}," 'submitting'",[33,6113,6114],{"class":43},"}>\n",[33,6116,6118,6121,6123,6125,6127,6130,6132,6134],{"class":35,"line":6117},138,[33,6119,6120],{"class":43},"        {status ",[33,6122,1283],{"class":39},[33,6124,6111],{"class":50},[33,6126,1288],{"class":39},[33,6128,6129],{"class":50}," 'Creating…'",[33,6131,1293],{"class":39},[33,6133,3778],{"class":50},[33,6135,238],{"class":43},[33,6137,6139,6141,6143],{"class":35,"line":6138},139,[33,6140,3785],{"class":43},[33,6142,417],{"class":173},[33,6144,432],{"class":43},[33,6146,6148],{"class":35,"line":6147},140,[33,6149,58],{"emptyLinePlaceholder":57},[33,6151,6153,6156,6158,6161,6164,6166,6168,6170,6172,6174,6177,6179],{"class":35,"line":6152},141,[33,6154,6155],{"class":43},"      {status ",[33,6157,1283],{"class":39},[33,6159,6160],{"class":50}," 'error'",[33,6162,6163],{"class":39}," &&",[33,6165,550],{"class":43},[33,6167,5706],{"class":173},[33,6169,5709],{"class":114},[33,6171,143],{"class":39},[33,6173,5714],{"class":50},[33,6175,6176],{"class":43},">Signup failed: {submitError}\u003C\u002F",[33,6178,5706],{"class":173},[33,6180,5722],{"class":43},[33,6182,6184,6186,6188,6191,6193,6195,6197,6199,6201,6204,6207,6209],{"class":35,"line":6183},142,[33,6185,6155],{"class":43},[33,6187,1283],{"class":39},[33,6189,6190],{"class":50}," 'success'",[33,6192,6163],{"class":39},[33,6194,550],{"class":43},[33,6196,5706],{"class":173},[33,6198,5709],{"class":114},[33,6200,143],{"class":39},[33,6202,6203],{"class":50},"\"success\"",[33,6205,6206],{"class":43},">Account created!\u003C\u002F",[33,6208,5706],{"class":173},[33,6210,5722],{"class":43},[33,6212,6214,6216,6218],{"class":35,"line":6213},143,[33,6215,438],{"class":43},[33,6217,368],{"class":173},[33,6219,432],{"class":43},[33,6221,6223],{"class":35,"line":6222},144,[33,6224,232],{"class":43},[33,6226,6228],{"class":35,"line":6227},145,[33,6229,6230],{"class":64},"  \u002F\u002F useReducer keeps all form state transitions in one testable reducer function.\n",[33,6232,6234],{"class":35,"line":6233},146,[33,6235,6236],{"class":64},"  \u002F\u002F The component stays declarative — dispatch actions, read state, render.\n",[33,6238,6240],{"class":35,"line":6239},147,[33,6241,238],{"class":43},[14,6243,6245],{"id":6244},"validation-patterns","Validation Patterns",[19,6247,6249],{"filename":6248,"language":22},"validation_patterns.js",[24,6250,6252],{"className":26,"code":6251,"language":22,"meta":28,"style":28},"import { useState, useCallback } from 'react'\n\n\u002F\u002F Validate on blur (immediate feedback) + validate on submit (final gate)\nfunction ValidatedForm() {\n  const [form, setForm] = useState({ email: '', password: '' })\n  const [errors, setErrors] = useState({})\n  const [touched, setTouched] = useState({})\n\n  function validate(values) {\n    const next = {}\n    if (!values.email) next.email = 'Email is required'\n    else if (!\u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F.test(values.email)) next.email = 'Invalid email format'\n    if (!values.password) next.password = 'Password is required'\n    else if (values.password.length \u003C 8) next.password = 'Password must be 8+ characters'\n    return next\n  }\n\n  function handleChange(e) {\n    const { name, value } = e.target\n    setForm(prev => ({ ...prev, [name]: value }))\n    if (touched[name]) {\n      setErrors(validate({ ...form, [name]: value }))\n    }\n  }\n\n  function handleBlur(e) {\n    const { name } = e.target\n    setTouched(prev => ({ ...prev, [name]: true }))\n    const fieldErrors = validate(form)\n    setErrors(prev => ({ ...prev, [name]: fieldErrors[name] }))\n  }\n\n  async function handleSubmit(e) {\n    e.preventDefault()\n    const fieldErrors = validate(form)\n    setErrors(fieldErrors)\n    setTouched({ email: true, password: true })\n    if (Object.keys(fieldErrors).length > 0) return\n    await submitForm(form)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit} noValidate>\n      \u003Cinput\n        name=\"email\"\n        value={form.email}\n        onChange={handleChange}\n        onBlur={handleBlur}\n      \u002F>\n      {touched.email && errors.email && \u003Cspan className=\"error\">{errors.email}\u003C\u002Fspan>}\n\n      \u003Cinput\n        name=\"password\"\n        type=\"password\"\n        value={form.password}\n        onChange={handleChange}\n        onBlur={handleBlur}\n      \u002F>\n      {touched.password && errors.password && \u003Cspan className=\"error\">{errors.password}\u003C\u002Fspan>}\n\n      \u003Cbutton type=\"submit\">Submit\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n  \u002F\u002F noValidate disables browser validation popups — we use custom JS validation.\n  \u002F\u002F HTML constraint attributes (required, pattern) still work for CSS :invalid.\n}\n\n\u002F\u002F Cross-field validation\nfunction PasswordMatchForm() {\n  const [form, setForm] = useState({ password: '', confirmPassword: '' })\n  const [errors, setErrors] = useState({})\n\n  function validate(values) {\n    const next = {}\n    if (values.password !== values.confirmPassword) {\n      next.confirmPassword = 'Passwords do not match'\n    }\n    return next\n  }\n\n  function handleSubmit(e) {\n    e.preventDefault()\n    const fieldErrors = validate(form)\n    setErrors(fieldErrors)\n    if (Object.keys(fieldErrors).length === 0) submit(form)\n  }\n\n  return (\n    \u003Cform onSubmit={handleSubmit} noValidate>\n      \u003Cinput\n        name=\"password\"\n        type=\"password\"\n        value={form.password}\n        onChange={e => setForm(prev => ({ ...prev, password: e.target.value }))}\n      \u002F>\n      \u003Cinput\n        name=\"confirmPassword\"\n        type=\"password\"\n        value={form.confirmPassword}\n        onChange={e => {\n          const next = { ...form, confirmPassword: e.target.value }\n          setForm(next)\n          setErrors(validate(next))\n        }}\n      \u002F>\n      {errors.confirmPassword && \u003Cspan className=\"error\">{errors.confirmPassword}\u003C\u002Fspan>}\n      \u003Cbutton type=\"submit\">Submit\u003C\u002Fbutton>\n    \u003C\u002Fform>\n  )\n}\n",[30,6253,6254,6265,6269,6274,6283,6312,6334,6355,6359,6371,6382,6398,6465,6481,6504,6511,6515,6519,6531,6549,6567,6574,6590,6594,6598,6602,6614,6628,6651,6664,6682,6686,6690,6704,6712,6724,6731,6745,6766,6776,6780,6784,6790,6806,6812,6821,6831,6839,6848,6852,6879,6883,6889,6897,6905,6914,6922,6930,6934,6961,6965,6983,6991,6995,7000,7005,7009,7013,7018,7027,7057,7077,7081,7093,7103,7115,7125,7129,7135,7139,7143,7155,7163,7175,7181,7205,7209,7213,7219,7235,7241,7249,7257,7265,7293,7297,7303,7312,7320,7329,7343,7359,7367,7379,7384,7388,7412,7430,7438,7442],{"__ignoreMap":28},[33,6255,6256,6258,6261,6263],{"class":35,"line":36},[33,6257,40],{"class":39},[33,6259,6260],{"class":43}," { useState, useCallback } ",[33,6262,47],{"class":39},[33,6264,51],{"class":50},[33,6266,6267],{"class":35,"line":54},[33,6268,58],{"emptyLinePlaceholder":57},[33,6270,6271],{"class":35,"line":61},[33,6272,6273],{"class":64},"\u002F\u002F Validate on blur (immediate feedback) + validate on submit (final gate)\n",[33,6275,6276,6278,6281],{"class":35,"line":68},[33,6277,111],{"class":39},[33,6279,6280],{"class":114}," ValidatedForm",[33,6282,118],{"class":43},[33,6284,6285,6287,6289,6291,6293,6295,6297,6299,6301,6304,6306,6308,6310],{"class":35,"line":74},[33,6286,124],{"class":39},[33,6288,127],{"class":43},[33,6290,368],{"class":130},[33,6292,134],{"class":43},[33,6294,4093],{"class":130},[33,6296,140],{"class":43},[33,6298,143],{"class":39},[33,6300,146],{"class":114},[33,6302,6303],{"class":43},"({ email: ",[33,6305,152],{"class":50},[33,6307,4593],{"class":43},[33,6309,152],{"class":50},[33,6311,5518],{"class":43},[33,6313,6314,6316,6318,6320,6322,6325,6327,6329,6331],{"class":35,"line":79},[33,6315,124],{"class":39},[33,6317,127],{"class":43},[33,6319,5258],{"class":130},[33,6321,134],{"class":43},[33,6323,6324],{"class":130},"setErrors",[33,6326,140],{"class":43},[33,6328,143],{"class":39},[33,6330,146],{"class":114},[33,6332,6333],{"class":43},"({})\n",[33,6335,6336,6338,6340,6342,6344,6347,6349,6351,6353],{"class":35,"line":85},[33,6337,124],{"class":39},[33,6339,127],{"class":43},[33,6341,5263],{"class":130},[33,6343,134],{"class":43},[33,6345,6346],{"class":130},"setTouched",[33,6348,140],{"class":43},[33,6350,143],{"class":39},[33,6352,146],{"class":114},[33,6354,6333],{"class":43},[33,6356,6357],{"class":35,"line":91},[33,6358,58],{"emptyLinePlaceholder":57},[33,6360,6361,6363,6365,6367,6369],{"class":35,"line":97},[33,6362,308],{"class":39},[33,6364,5174],{"class":114},[33,6366,149],{"class":43},[33,6368,5117],{"class":210},[33,6370,318],{"class":43},[33,6372,6373,6375,6378,6380],{"class":35,"line":103},[33,6374,851],{"class":39},[33,6376,6377],{"class":130}," next",[33,6379,287],{"class":39},[33,6381,5131],{"class":43},[33,6383,6384,6386,6388,6390,6393,6395],{"class":35,"line":108},[33,6385,2123],{"class":39},[33,6387,2126],{"class":43},[33,6389,2129],{"class":39},[33,6391,6392],{"class":43},"values.email) next.email ",[33,6394,143],{"class":39},[33,6396,6397],{"class":50}," 'Email is required'\n",[33,6399,6400,6403,6406,6408,6410,6412,6415,6418,6420,6423,6426,6429,6431,6433,6435,6437,6441,6443,6445,6447,6450,6452,6454,6457,6460,6462],{"class":35,"line":121},[33,6401,6402],{"class":39},"    else",[33,6404,6405],{"class":39}," if",[33,6407,2126],{"class":43},[33,6409,2129],{"class":39},[33,6411,867],{"class":50},[33,6413,6414],{"class":39},"^",[33,6416,6417],{"class":130},"[",[33,6419,6414],{"class":39},[33,6421,6422],{"class":130},"\\s@]",[33,6424,6425],{"class":39},"+",[33,6427,6428],{"class":934},"@",[33,6430,6417],{"class":130},[33,6432,6414],{"class":39},[33,6434,6422],{"class":130},[33,6436,6425],{"class":39},[33,6438,6440],{"class":6439},"snRuI","\\.",[33,6442,6417],{"class":130},[33,6444,6414],{"class":39},[33,6446,6422],{"class":130},[33,6448,6449],{"class":39},"+$",[33,6451,867],{"class":50},[33,6453,2261],{"class":43},[33,6455,6456],{"class":114},"test",[33,6458,6459],{"class":43},"(values.email)) next.email ",[33,6461,143],{"class":39},[33,6463,6464],{"class":50}," 'Invalid email format'\n",[33,6466,6467,6469,6471,6473,6476,6478],{"class":35,"line":158},[33,6468,2123],{"class":39},[33,6470,2126],{"class":43},[33,6472,2129],{"class":39},[33,6474,6475],{"class":43},"values.password) next.password ",[33,6477,143],{"class":39},[33,6479,6480],{"class":50}," 'Password is required'\n",[33,6482,6483,6485,6487,6490,6492,6494,6496,6499,6501],{"class":35,"line":167},[33,6484,6402],{"class":39},[33,6486,6405],{"class":39},[33,6488,6489],{"class":43}," (values.password.",[33,6491,5007],{"class":130},[33,6493,550],{"class":39},[33,6495,5086],{"class":130},[33,6497,6498],{"class":43},") next.password ",[33,6500,143],{"class":39},[33,6502,6503],{"class":50}," 'Password must be 8+ characters'\n",[33,6505,6506,6508],{"class":35,"line":177},[33,6507,3918],{"class":39},[33,6509,6510],{"class":43}," next\n",[33,6512,6513],{"class":35,"line":188},[33,6514,348],{"class":43},[33,6516,6517],{"class":35,"line":199},[33,6518,58],{"emptyLinePlaceholder":57},[33,6520,6521,6523,6525,6527,6529],{"class":35,"line":223},[33,6522,308],{"class":39},[33,6524,840],{"class":114},[33,6526,149],{"class":43},[33,6528,211],{"class":210},[33,6530,318],{"class":43},[33,6532,6533,6535,6537,6539,6541,6543,6545,6547],{"class":35,"line":229},[33,6534,851],{"class":39},[33,6536,4166],{"class":43},[33,6538,531],{"class":130},[33,6540,134],{"class":43},[33,6542,608],{"class":130},[33,6544,4185],{"class":43},[33,6546,143],{"class":39},[33,6548,4190],{"class":43},[33,6550,6551,6553,6555,6557,6559,6562,6564],{"class":35,"line":235},[33,6552,4195],{"class":114},[33,6554,149],{"class":43},[33,6556,4200],{"class":210},[33,6558,214],{"class":39},[33,6560,6561],{"class":43}," ({ ",[33,6563,4726],{"class":39},[33,6565,6566],{"class":43},"prev, [name]: value }))\n",[33,6568,6569,6571],{"class":35,"line":241},[33,6570,2123],{"class":39},[33,6572,6573],{"class":43}," (touched[name]) {\n",[33,6575,6576,6579,6581,6583,6585,6587],{"class":35,"line":246},[33,6577,6578],{"class":114},"      setErrors",[33,6580,149],{"class":43},[33,6582,5150],{"class":114},[33,6584,593],{"class":43},[33,6586,4726],{"class":39},[33,6588,6589],{"class":43},"form, [name]: value }))\n",[33,6591,6592],{"class":35,"line":252},[33,6593,1555],{"class":43},[33,6595,6596],{"class":35,"line":258},[33,6597,348],{"class":43},[33,6599,6600],{"class":35,"line":264},[33,6601,58],{"emptyLinePlaceholder":57},[33,6603,6604,6606,6608,6610,6612],{"class":35,"line":269},[33,6605,308],{"class":39},[33,6607,5353],{"class":114},[33,6609,149],{"class":43},[33,6611,211],{"class":210},[33,6613,318],{"class":43},[33,6615,6616,6618,6620,6622,6624,6626],{"class":35,"line":279},[33,6617,851],{"class":39},[33,6619,4166],{"class":43},[33,6621,531],{"class":130},[33,6623,4185],{"class":43},[33,6625,143],{"class":39},[33,6627,4190],{"class":43},[33,6629,6630,6633,6635,6637,6639,6641,6643,6646,6648],{"class":35,"line":300},[33,6631,6632],{"class":114},"    setTouched",[33,6634,149],{"class":43},[33,6636,4200],{"class":210},[33,6638,214],{"class":39},[33,6640,6561],{"class":43},[33,6642,4726],{"class":39},[33,6644,6645],{"class":43},"prev, [name]: ",[33,6647,3171],{"class":130},[33,6649,6650],{"class":43}," }))\n",[33,6652,6653,6655,6658,6660,6662],{"class":35,"line":305},[33,6654,851],{"class":39},[33,6656,6657],{"class":130}," fieldErrors",[33,6659,287],{"class":39},[33,6661,5174],{"class":114},[33,6663,4307],{"class":43},[33,6665,6666,6669,6671,6673,6675,6677,6679],{"class":35,"line":321},[33,6667,6668],{"class":114},"    setErrors",[33,6670,149],{"class":43},[33,6672,4200],{"class":210},[33,6674,214],{"class":39},[33,6676,6561],{"class":43},[33,6678,4726],{"class":39},[33,6680,6681],{"class":43},"prev, [name]: fieldErrors[name] }))\n",[33,6683,6684],{"class":35,"line":333},[33,6685,348],{"class":43},[33,6687,6688],{"class":35,"line":345},[33,6689,58],{"emptyLinePlaceholder":57},[33,6691,6692,6694,6696,6698,6700,6702],{"class":35,"line":351},[33,6693,3351],{"class":39},[33,6695,3354],{"class":39},[33,6697,311],{"class":114},[33,6699,149],{"class":43},[33,6701,211],{"class":210},[33,6703,318],{"class":43},[33,6705,6706,6708,6710],{"class":35,"line":356},[33,6707,324],{"class":43},[33,6709,327],{"class":114},[33,6711,330],{"class":43},[33,6713,6714,6716,6718,6720,6722],{"class":35,"line":363},[33,6715,851],{"class":39},[33,6717,6657],{"class":130},[33,6719,287],{"class":39},[33,6721,5174],{"class":114},[33,6723,4307],{"class":43},[33,6725,6726,6728],{"class":35,"line":379},[33,6727,6668],{"class":114},[33,6729,6730],{"class":43},"(fieldErrors)\n",[33,6732,6733,6735,6737,6739,6741,6743],{"class":35,"line":412},[33,6734,6632],{"class":114},[33,6736,6303],{"class":43},[33,6738,3171],{"class":130},[33,6740,4593],{"class":43},[33,6742,3171],{"class":130},[33,6744,5518],{"class":43},[33,6746,6747,6749,6751,6753,6756,6758,6760,6762,6764],{"class":35,"line":435},[33,6748,2123],{"class":39},[33,6750,5482],{"class":43},[33,6752,5485],{"class":114},[33,6754,6755],{"class":43},"(fieldErrors).",[33,6757,5007],{"class":130},[33,6759,5493],{"class":39},[33,6761,5496],{"class":130},[33,6763,984],{"class":43},[33,6765,2135],{"class":39},[33,6767,6768,6771,6774],{"class":35,"line":445},[33,6769,6770],{"class":39},"    await",[33,6772,6773],{"class":114}," submitForm",[33,6775,4307],{"class":43},[33,6777,6778],{"class":35,"line":450},[33,6779,348],{"class":43},[33,6781,6782],{"class":35,"line":1200},[33,6783,58],{"emptyLinePlaceholder":57},[33,6785,6786,6788],{"class":35,"line":1227},[33,6787,161],{"class":39},[33,6789,164],{"class":43},[33,6791,6792,6794,6796,6798,6800,6802,6804],{"class":35,"line":1240},[33,6793,170],{"class":43},[33,6795,368],{"class":173},[33,6797,371],{"class":114},[33,6799,143],{"class":39},[33,6801,1863],{"class":43},[33,6803,5608],{"class":114},[33,6805,432],{"class":43},[33,6807,6808,6810],{"class":35,"line":1270},[33,6809,382],{"class":43},[33,6811,174],{"class":173},[33,6813,6814,6817,6819],{"class":35,"line":1330},[33,6815,6816],{"class":114},"        name",[33,6818,143],{"class":39},[33,6820,185],{"class":50},[33,6822,6823,6826,6828],{"class":35,"line":1339},[33,6824,6825],{"class":114},"        value",[33,6827,143],{"class":39},[33,6829,6830],{"class":43},"{form.email}\n",[33,6832,6833,6835,6837],{"class":35,"line":1344},[33,6834,2390],{"class":114},[33,6836,143],{"class":39},[33,6838,1055],{"class":43},[33,6840,6841,6844,6846],{"class":35,"line":1396},[33,6842,6843],{"class":114},"        onBlur",[33,6845,143],{"class":39},[33,6847,5671],{"class":43},[33,6849,6850],{"class":35,"line":1970},[33,6851,2400],{"class":43},[33,6853,6854,6857,6859,6861,6863,6865,6867,6869,6871,6873,6875,6877],{"class":35,"line":1979},[33,6855,6856],{"class":43},"      {touched.email ",[33,6858,2408],{"class":39},[33,6860,5825],{"class":43},[33,6862,2408],{"class":39},[33,6864,550],{"class":43},[33,6866,33],{"class":173},[33,6868,5709],{"class":114},[33,6870,143],{"class":39},[33,6872,5714],{"class":50},[33,6874,5840],{"class":43},[33,6876,33],{"class":173},[33,6878,5722],{"class":43},[33,6880,6881],{"class":35,"line":1984},[33,6882,58],{"emptyLinePlaceholder":57},[33,6884,6885,6887],{"class":35,"line":2515},[33,6886,382],{"class":43},[33,6888,174],{"class":173},[33,6890,6891,6893,6895],{"class":35,"line":2528},[33,6892,6816],{"class":114},[33,6894,143],{"class":39},[33,6896,5884],{"class":50},[33,6898,6899,6901,6903],{"class":35,"line":2537},[33,6900,2360],{"class":114},[33,6902,143],{"class":39},[33,6904,5884],{"class":50},[33,6906,6907,6909,6911],{"class":35,"line":2555},[33,6908,6825],{"class":114},[33,6910,143],{"class":39},[33,6912,6913],{"class":43},"{form.password}\n",[33,6915,6916,6918,6920],{"class":35,"line":2596},[33,6917,2390],{"class":114},[33,6919,143],{"class":39},[33,6921,1055],{"class":43},[33,6923,6924,6926,6928],{"class":35,"line":2605},[33,6925,6843],{"class":114},[33,6927,143],{"class":39},[33,6929,5671],{"class":43},[33,6931,6932],{"class":35,"line":2610},[33,6933,2400],{"class":43},[33,6935,6936,6939,6941,6943,6945,6947,6949,6951,6953,6955,6957,6959],{"class":35,"line":2615},[33,6937,6938],{"class":43},"      {touched.password ",[33,6940,2408],{"class":39},[33,6942,5947],{"class":43},[33,6944,2408],{"class":39},[33,6946,550],{"class":43},[33,6948,33],{"class":173},[33,6950,5709],{"class":114},[33,6952,143],{"class":39},[33,6954,5714],{"class":50},[33,6956,5962],{"class":43},[33,6958,33],{"class":173},[33,6960,5722],{"class":43},[33,6962,6963],{"class":35,"line":2622},[33,6964,58],{"emptyLinePlaceholder":57},[33,6966,6967,6969,6971,6973,6975,6977,6979,6981],{"class":35,"line":2635},[33,6968,382],{"class":43},[33,6970,417],{"class":173},[33,6972,388],{"class":114},[33,6974,143],{"class":39},[33,6976,424],{"class":50},[33,6978,427],{"class":43},[33,6980,417],{"class":173},[33,6982,432],{"class":43},[33,6984,6985,6987,6989],{"class":35,"line":2669},[33,6986,438],{"class":43},[33,6988,368],{"class":173},[33,6990,432],{"class":43},[33,6992,6993],{"class":35,"line":2688},[33,6994,232],{"class":43},[33,6996,6997],{"class":35,"line":2697},[33,6998,6999],{"class":64},"  \u002F\u002F noValidate disables browser validation popups — we use custom JS validation.\n",[33,7001,7002],{"class":35,"line":2702},[33,7003,7004],{"class":64},"  \u002F\u002F HTML constraint attributes (required, pattern) still work for CSS :invalid.\n",[33,7006,7007],{"class":35,"line":2707},[33,7008,238],{"class":43},[33,7010,7011],{"class":35,"line":2712},[33,7012,58],{"emptyLinePlaceholder":57},[33,7014,7015],{"class":35,"line":2718},[33,7016,7017],{"class":64},"\u002F\u002F Cross-field validation\n",[33,7019,7020,7022,7025],{"class":35,"line":2728},[33,7021,111],{"class":39},[33,7023,7024],{"class":114}," PasswordMatchForm",[33,7026,118],{"class":43},[33,7028,7029,7031,7033,7035,7037,7039,7041,7043,7045,7048,7050,7053,7055],{"class":35,"line":2755},[33,7030,124],{"class":39},[33,7032,127],{"class":43},[33,7034,368],{"class":130},[33,7036,134],{"class":43},[33,7038,4093],{"class":130},[33,7040,140],{"class":43},[33,7042,143],{"class":39},[33,7044,146],{"class":114},[33,7046,7047],{"class":43},"({ password: ",[33,7049,152],{"class":50},[33,7051,7052],{"class":43},", confirmPassword: ",[33,7054,152],{"class":50},[33,7056,5518],{"class":43},[33,7058,7059,7061,7063,7065,7067,7069,7071,7073,7075],{"class":35,"line":2762},[33,7060,124],{"class":39},[33,7062,127],{"class":43},[33,7064,5258],{"class":130},[33,7066,134],{"class":43},[33,7068,6324],{"class":130},[33,7070,140],{"class":43},[33,7072,143],{"class":39},[33,7074,146],{"class":114},[33,7076,6333],{"class":43},[33,7078,7079],{"class":35,"line":2769},[33,7080,58],{"emptyLinePlaceholder":57},[33,7082,7083,7085,7087,7089,7091],{"class":35,"line":2778},[33,7084,308],{"class":39},[33,7086,5174],{"class":114},[33,7088,149],{"class":43},[33,7090,5117],{"class":210},[33,7092,318],{"class":43},[33,7094,7095,7097,7099,7101],{"class":35,"line":2788},[33,7096,851],{"class":39},[33,7098,6377],{"class":130},[33,7100,287],{"class":39},[33,7102,5131],{"class":43},[33,7104,7105,7107,7110,7112],{"class":35,"line":2806},[33,7106,2123],{"class":39},[33,7108,7109],{"class":43}," (values.password ",[33,7111,4277],{"class":39},[33,7113,7114],{"class":43}," values.confirmPassword) {\n",[33,7116,7117,7120,7122],{"class":35,"line":2811},[33,7118,7119],{"class":43},"      next.confirmPassword ",[33,7121,143],{"class":39},[33,7123,7124],{"class":50}," 'Passwords do not match'\n",[33,7126,7127],{"class":35,"line":2816},[33,7128,1555],{"class":43},[33,7130,7131,7133],{"class":35,"line":2822},[33,7132,3918],{"class":39},[33,7134,6510],{"class":43},[33,7136,7137],{"class":35,"line":2828},[33,7138,348],{"class":43},[33,7140,7141],{"class":35,"line":5449},[33,7142,58],{"emptyLinePlaceholder":57},[33,7144,7145,7147,7149,7151,7153],{"class":35,"line":5464},[33,7146,308],{"class":39},[33,7148,311],{"class":114},[33,7150,149],{"class":43},[33,7152,211],{"class":210},[33,7154,318],{"class":43},[33,7156,7157,7159,7161],{"class":35,"line":5477},[33,7158,324],{"class":43},[33,7160,327],{"class":114},[33,7162,330],{"class":43},[33,7164,7165,7167,7169,7171,7173],{"class":35,"line":5503},[33,7166,851],{"class":39},[33,7168,6657],{"class":130},[33,7170,287],{"class":39},[33,7172,5174],{"class":114},[33,7174,4307],{"class":43},[33,7176,7177,7179],{"class":35,"line":5508},[33,7178,6668],{"class":114},[33,7180,6730],{"class":43},[33,7182,7183,7185,7187,7189,7191,7193,7196,7198,7200,7203],{"class":35,"line":5521},[33,7184,2123],{"class":39},[33,7186,5482],{"class":43},[33,7188,5485],{"class":114},[33,7190,6755],{"class":43},[33,7192,5007],{"class":130},[33,7194,7195],{"class":39}," ===",[33,7197,5496],{"class":130},[33,7199,984],{"class":43},[33,7201,7202],{"class":114},"submit",[33,7204,4307],{"class":43},[33,7206,7207],{"class":35,"line":5528},[33,7208,348],{"class":43},[33,7210,7211],{"class":35,"line":5537},[33,7212,58],{"emptyLinePlaceholder":57},[33,7214,7215,7217],{"class":35,"line":5550},[33,7216,161],{"class":39},[33,7218,164],{"class":43},[33,7220,7221,7223,7225,7227,7229,7231,7233],{"class":35,"line":5559},[33,7222,170],{"class":43},[33,7224,368],{"class":173},[33,7226,371],{"class":114},[33,7228,143],{"class":39},[33,7230,1863],{"class":43},[33,7232,5608],{"class":114},[33,7234,432],{"class":43},[33,7236,7237,7239],{"class":35,"line":5572},[33,7238,382],{"class":43},[33,7240,174],{"class":173},[33,7242,7243,7245,7247],{"class":35,"line":5577},[33,7244,6816],{"class":114},[33,7246,143],{"class":39},[33,7248,5884],{"class":50},[33,7250,7251,7253,7255],{"class":35,"line":5583},[33,7252,2360],{"class":114},[33,7254,143],{"class":39},[33,7256,5884],{"class":50},[33,7258,7259,7261,7263],{"class":35,"line":5588},[33,7260,6825],{"class":114},[33,7262,143],{"class":39},[33,7264,6913],{"class":43},[33,7266,7267,7269,7271,7273,7275,7277,7280,7282,7284,7286,7288,7290],{"class":35,"line":5595},[33,7268,2390],{"class":114},[33,7270,143],{"class":39},[33,7272,207],{"class":43},[33,7274,211],{"class":210},[33,7276,214],{"class":39},[33,7278,7279],{"class":114}," setForm",[33,7281,149],{"class":43},[33,7283,4200],{"class":210},[33,7285,214],{"class":39},[33,7287,6561],{"class":43},[33,7289,4726],{"class":39},[33,7291,7292],{"class":43},"prev, password: e.target.value }))}\n",[33,7294,7295],{"class":35,"line":5613},[33,7296,2400],{"class":43},[33,7298,7299,7301],{"class":35,"line":5623},[33,7300,382],{"class":43},[33,7302,174],{"class":173},[33,7304,7305,7307,7309],{"class":35,"line":5631},[33,7306,6816],{"class":114},[33,7308,143],{"class":39},[33,7310,7311],{"class":50},"\"confirmPassword\"\n",[33,7313,7314,7316,7318],{"class":35,"line":5642},[33,7315,2360],{"class":114},[33,7317,143],{"class":39},[33,7319,5884],{"class":50},[33,7321,7322,7324,7326],{"class":35,"line":5653},[33,7323,6825],{"class":114},[33,7325,143],{"class":39},[33,7327,7328],{"class":43},"{form.confirmPassword}\n",[33,7330,7331,7333,7335,7337,7339,7341],{"class":35,"line":5663},[33,7332,2390],{"class":114},[33,7334,143],{"class":39},[33,7336,207],{"class":43},[33,7338,211],{"class":210},[33,7340,214],{"class":39},[33,7342,1535],{"class":43},[33,7344,7345,7348,7350,7352,7354,7356],{"class":35,"line":5674},[33,7346,7347],{"class":39},"          const",[33,7349,6377],{"class":130},[33,7351,287],{"class":39},[33,7353,4166],{"class":43},[33,7355,4726],{"class":39},[33,7357,7358],{"class":43},"form, confirmPassword: e.target.value }\n",[33,7360,7361,7364],{"class":35,"line":5685},[33,7362,7363],{"class":114},"          setForm",[33,7365,7366],{"class":43},"(next)\n",[33,7368,7369,7372,7374,7376],{"class":35,"line":5691},[33,7370,7371],{"class":114},"          setErrors",[33,7373,149],{"class":43},[33,7375,5150],{"class":114},[33,7377,7378],{"class":43},"(next))\n",[33,7380,7381],{"class":35,"line":5725},[33,7382,7383],{"class":43},"        }}\n",[33,7385,7386],{"class":35,"line":5734},[33,7387,2400],{"class":43},[33,7389,7390,7393,7395,7397,7399,7401,7403,7405,7408,7410],{"class":35,"line":5739},[33,7391,7392],{"class":43},"      {errors.confirmPassword ",[33,7394,2408],{"class":39},[33,7396,550],{"class":43},[33,7398,33],{"class":173},[33,7400,5709],{"class":114},[33,7402,143],{"class":39},[33,7404,5714],{"class":50},[33,7406,7407],{"class":43},">{errors.confirmPassword}\u003C\u002F",[33,7409,33],{"class":173},[33,7411,5722],{"class":43},[33,7413,7414,7416,7418,7420,7422,7424,7426,7428],{"class":35,"line":5748},[33,7415,382],{"class":43},[33,7417,417],{"class":173},[33,7419,388],{"class":114},[33,7421,143],{"class":39},[33,7423,424],{"class":50},[33,7425,427],{"class":43},[33,7427,417],{"class":173},[33,7429,432],{"class":43},[33,7431,7432,7434,7436],{"class":35,"line":5755},[33,7433,438],{"class":43},[33,7435,368],{"class":173},[33,7437,432],{"class":43},[33,7439,7440],{"class":35,"line":5764},[33,7441,232],{"class":43},[33,7443,7444],{"class":35,"line":5774},[33,7445,238],{"class":43},[14,7447,7449],{"id":7448},"tips-tricks","💡 Tips & Tricks",[19,7451,7453],{"filename":7452,"language":22},"tips.js",[24,7454,7456],{"className":26,"code":7455,"language":22,"meta":28,"style":28},"\u002F\u002F [Idiom] Default to controlled for anything with validation, formatting, or cross-field\n\u002F\u002F logic. Reach for uncontrolled only for simple submit-time-only fields or file inputs.\n\n\u002F\u002F [Debug] \"Component is changing an uncontrolled input to controlled\" → initial state\n\u002F\u002F is undefined. useState() with no arg → undefined → value={undefined} = uncontrolled.\n\u002F\u002F Always initialize: useState('') for text, useState(false) for checkboxes.\n\n\u002F\u002F [Performance] For 50+ field forms or forms in frequently-re-rendering lists,\n\u002F\u002F react-hook-form's uncontrolled-by-default registration avoids per-keystroke re-renders.\n\n\u002F\u002F [Idiom] Use a single state object + name-attribute-keyed handleChange once a form\n\u002F\u002F exceeds ~5 fields. One useState per field stops scaling readably before that.\n\n\u002F\u002F [Debug] noValidate on \u003Cform> disables browser validation POPUPS only.\n\u002F\u002F HTML constraint attributes (required, pattern) still work for CSS :invalid styling.\n\u002F\u002F You still need e.preventDefault() in your submit handler regardless.\n\n\u002F\u002F [Idiom] For complex forms (multi-step, dependent validation, async submit state),\n\u002F\u002F useReducer centralizes all state transitions in one testable function. See Ch 10.\n\n\u002F\u002F [Safety] Always clean up object URLs: URL.revokeObjectURL(previewUrl) in a useEffect\n\u002F\u002F cleanup. Failing to revoke leaks memory (the blob stays until page unloads).\n",[30,7457,7458,7463,7468,7472,7477,7482,7487,7491,7496,7501,7505,7510,7515,7519,7524,7529,7534,7538,7543,7548,7552,7557],{"__ignoreMap":28},[33,7459,7460],{"class":35,"line":36},[33,7461,7462],{"class":64},"\u002F\u002F [Idiom] Default to controlled for anything with validation, formatting, or cross-field\n",[33,7464,7465],{"class":35,"line":54},[33,7466,7467],{"class":64},"\u002F\u002F logic. Reach for uncontrolled only for simple submit-time-only fields or file inputs.\n",[33,7469,7470],{"class":35,"line":61},[33,7471,58],{"emptyLinePlaceholder":57},[33,7473,7474],{"class":35,"line":68},[33,7475,7476],{"class":64},"\u002F\u002F [Debug] \"Component is changing an uncontrolled input to controlled\" → initial state\n",[33,7478,7479],{"class":35,"line":74},[33,7480,7481],{"class":64},"\u002F\u002F is undefined. useState() with no arg → undefined → value={undefined} = uncontrolled.\n",[33,7483,7484],{"class":35,"line":79},[33,7485,7486],{"class":64},"\u002F\u002F Always initialize: useState('') for text, useState(false) for checkboxes.\n",[33,7488,7489],{"class":35,"line":85},[33,7490,58],{"emptyLinePlaceholder":57},[33,7492,7493],{"class":35,"line":91},[33,7494,7495],{"class":64},"\u002F\u002F [Performance] For 50+ field forms or forms in frequently-re-rendering lists,\n",[33,7497,7498],{"class":35,"line":97},[33,7499,7500],{"class":64},"\u002F\u002F react-hook-form's uncontrolled-by-default registration avoids per-keystroke re-renders.\n",[33,7502,7503],{"class":35,"line":103},[33,7504,58],{"emptyLinePlaceholder":57},[33,7506,7507],{"class":35,"line":108},[33,7508,7509],{"class":64},"\u002F\u002F [Idiom] Use a single state object + name-attribute-keyed handleChange once a form\n",[33,7511,7512],{"class":35,"line":121},[33,7513,7514],{"class":64},"\u002F\u002F exceeds ~5 fields. One useState per field stops scaling readably before that.\n",[33,7516,7517],{"class":35,"line":158},[33,7518,58],{"emptyLinePlaceholder":57},[33,7520,7521],{"class":35,"line":167},[33,7522,7523],{"class":64},"\u002F\u002F [Debug] noValidate on \u003Cform> disables browser validation POPUPS only.\n",[33,7525,7526],{"class":35,"line":177},[33,7527,7528],{"class":64},"\u002F\u002F HTML constraint attributes (required, pattern) still work for CSS :invalid styling.\n",[33,7530,7531],{"class":35,"line":188},[33,7532,7533],{"class":64},"\u002F\u002F You still need e.preventDefault() in your submit handler regardless.\n",[33,7535,7536],{"class":35,"line":199},[33,7537,58],{"emptyLinePlaceholder":57},[33,7539,7540],{"class":35,"line":223},[33,7541,7542],{"class":64},"\u002F\u002F [Idiom] For complex forms (multi-step, dependent validation, async submit state),\n",[33,7544,7545],{"class":35,"line":229},[33,7546,7547],{"class":64},"\u002F\u002F useReducer centralizes all state transitions in one testable function. See Ch 10.\n",[33,7549,7550],{"class":35,"line":235},[33,7551,58],{"emptyLinePlaceholder":57},[33,7553,7554],{"class":35,"line":241},[33,7555,7556],{"class":64},"\u002F\u002F [Safety] Always clean up object URLs: URL.revokeObjectURL(previewUrl) in a useEffect\n",[33,7558,7559],{"class":35,"line":246},[33,7560,7561],{"class":64},"\u002F\u002F cleanup. Failing to revoke leaks memory (the blob stays until page unloads).\n",[14,7563,7565],{"id":7564},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[19,7567,7569],{"filename":7568,"language":22},"edge_cases.js",[24,7570,7572],{"className":26,"code":7571,"language":22,"meta":28,"style":28},"\u002F\u002F [Gotcha] Controlled input with value but NO onChange → silently rejects all keyboard\n\u002F\u002F input. React overwrites the DOM value back to the unchanging state on every render.\n\u002F\u002F No error thrown — the input just looks broken\u002Fread-only.\n\n\u002F\u002F [Gotcha] File inputs can NEVER be controlled. Browsers refuse to let JS set a file\n\u002F\u002F input's value (security). Always use ref + .files[0].\n\n\u002F\u002F [Gotcha] Switching between controlled and uncontrolled mid-lifecycle (state starts\n\u002F\u002F as undefined, becomes a string) triggers the controlled\u002Funcontrolled warning.\n\u002F\u002F Always seed initial state with a typed empty value: '', 0, false — never undefined\u002Fnull.\n\n\u002F\u002F [Gotcha] defaultValue only applies ONCE at mount. Changing defaultValue on re-render\n\u002F\u002F does NOT update an already-mounted uncontrolled input. Remount via key or go controlled.\n\n\u002F\u002F [Gotcha] Checkboxes and radios use checked\u002FdefaultChecked, NOT value\u002FdefaultValue.\n\u002F\u002F Passing value to a checkbox sets the form submission value but does NOT control\n\u002F\u002F whether it's checked.\n\n\u002F\u002F [Gotcha] \u003Cselect multiple> with value={state} expects an ARRAY of selected option\n\u002F\u002F values, not a single string. value={['apple', 'banana']} not value=\"apple\".\n\n\u002F\u002F [Gotcha] \u003Cinput type=\"number\"> with value={NaN}: parseInt('') returns NaN,\n\u002F\u002F NaN || 0 evaluates to 0 (NaN is falsy). The input snaps to 0 when the user\n\u002F\u002F tries to clear it. Store the raw string and parse only on submit\u002Fblur.\n\n\u002F\u002F [Gotcha] FormData.entries() returns only the LAST value for fields with duplicate\n\u002F\u002F names (multiple checkboxes with name=\"interests\"). Use formData.getAll('interests')\n\u002F\u002F to get all values as an array.\n",[30,7573,7574,7579,7584,7589,7593,7598,7603,7607,7612,7617,7622,7626,7631,7636,7640,7645,7650,7655,7659,7664,7669,7673,7678,7683,7688,7692,7697,7702],{"__ignoreMap":28},[33,7575,7576],{"class":35,"line":36},[33,7577,7578],{"class":64},"\u002F\u002F [Gotcha] Controlled input with value but NO onChange → silently rejects all keyboard\n",[33,7580,7581],{"class":35,"line":54},[33,7582,7583],{"class":64},"\u002F\u002F input. React overwrites the DOM value back to the unchanging state on every render.\n",[33,7585,7586],{"class":35,"line":61},[33,7587,7588],{"class":64},"\u002F\u002F No error thrown — the input just looks broken\u002Fread-only.\n",[33,7590,7591],{"class":35,"line":68},[33,7592,58],{"emptyLinePlaceholder":57},[33,7594,7595],{"class":35,"line":74},[33,7596,7597],{"class":64},"\u002F\u002F [Gotcha] File inputs can NEVER be controlled. Browsers refuse to let JS set a file\n",[33,7599,7600],{"class":35,"line":79},[33,7601,7602],{"class":64},"\u002F\u002F input's value (security). Always use ref + .files[0].\n",[33,7604,7605],{"class":35,"line":85},[33,7606,58],{"emptyLinePlaceholder":57},[33,7608,7609],{"class":35,"line":91},[33,7610,7611],{"class":64},"\u002F\u002F [Gotcha] Switching between controlled and uncontrolled mid-lifecycle (state starts\n",[33,7613,7614],{"class":35,"line":97},[33,7615,7616],{"class":64},"\u002F\u002F as undefined, becomes a string) triggers the controlled\u002Funcontrolled warning.\n",[33,7618,7619],{"class":35,"line":103},[33,7620,7621],{"class":64},"\u002F\u002F Always seed initial state with a typed empty value: '', 0, false — never undefined\u002Fnull.\n",[33,7623,7624],{"class":35,"line":108},[33,7625,58],{"emptyLinePlaceholder":57},[33,7627,7628],{"class":35,"line":121},[33,7629,7630],{"class":64},"\u002F\u002F [Gotcha] defaultValue only applies ONCE at mount. Changing defaultValue on re-render\n",[33,7632,7633],{"class":35,"line":158},[33,7634,7635],{"class":64},"\u002F\u002F does NOT update an already-mounted uncontrolled input. Remount via key or go controlled.\n",[33,7637,7638],{"class":35,"line":167},[33,7639,58],{"emptyLinePlaceholder":57},[33,7641,7642],{"class":35,"line":177},[33,7643,7644],{"class":64},"\u002F\u002F [Gotcha] Checkboxes and radios use checked\u002FdefaultChecked, NOT value\u002FdefaultValue.\n",[33,7646,7647],{"class":35,"line":188},[33,7648,7649],{"class":64},"\u002F\u002F Passing value to a checkbox sets the form submission value but does NOT control\n",[33,7651,7652],{"class":35,"line":199},[33,7653,7654],{"class":64},"\u002F\u002F whether it's checked.\n",[33,7656,7657],{"class":35,"line":223},[33,7658,58],{"emptyLinePlaceholder":57},[33,7660,7661],{"class":35,"line":229},[33,7662,7663],{"class":64},"\u002F\u002F [Gotcha] \u003Cselect multiple> with value={state} expects an ARRAY of selected option\n",[33,7665,7666],{"class":35,"line":235},[33,7667,7668],{"class":64},"\u002F\u002F values, not a single string. value={['apple', 'banana']} not value=\"apple\".\n",[33,7670,7671],{"class":35,"line":241},[33,7672,58],{"emptyLinePlaceholder":57},[33,7674,7675],{"class":35,"line":246},[33,7676,7677],{"class":64},"\u002F\u002F [Gotcha] \u003Cinput type=\"number\"> with value={NaN}: parseInt('') returns NaN,\n",[33,7679,7680],{"class":35,"line":252},[33,7681,7682],{"class":64},"\u002F\u002F NaN || 0 evaluates to 0 (NaN is falsy). The input snaps to 0 when the user\n",[33,7684,7685],{"class":35,"line":258},[33,7686,7687],{"class":64},"\u002F\u002F tries to clear it. Store the raw string and parse only on submit\u002Fblur.\n",[33,7689,7690],{"class":35,"line":264},[33,7691,58],{"emptyLinePlaceholder":57},[33,7693,7694],{"class":35,"line":269},[33,7695,7696],{"class":64},"\u002F\u002F [Gotcha] FormData.entries() returns only the LAST value for fields with duplicate\n",[33,7698,7699],{"class":35,"line":279},[33,7700,7701],{"class":64},"\u002F\u002F names (multiple checkboxes with name=\"interests\"). Use formData.getAll('interests')\n",[33,7703,7704],{"class":35,"line":300},[33,7705,7706],{"class":64},"\u002F\u002F to get all values as an array.\n",[14,7708,7710],{"id":7709},"spot-the-bug","🧠 Spot the Bug",[5706,7712,7713,7714,4231],{},"A \"quantity\" stepper input is supposed to let users type any number, but every time they try to clear the field to type a new value, it immediately snaps back to ",[30,7715,890],{},[19,7717,7719],{"filename":7718,"language":22},"spot_the_bug.js",[24,7720,7722],{"className":26,"code":7721,"language":22,"meta":28,"style":28},"function QuantityInput({ onChange }) {\n  const [quantity, setQuantity] = useState(1)\n\n  function handleChange(e) {\n    const parsed = parseInt(e.target.value, 10)\n    setQuantity(parsed)\n    onChange(parsed)\n  }\n\n  return \u003Cinput type=\"number\" value={quantity || 0} onChange={handleChange} \u002F>\n}\n",[30,7723,7724,7737,7764,7768,7780,7799,7807,7814,7818,7822,7857],{"__ignoreMap":28},[33,7725,7726,7728,7731,7733,7735],{"class":35,"line":36},[33,7727,111],{"class":39},[33,7729,7730],{"class":114}," QuantityInput",[33,7732,593],{"class":43},[33,7734,643],{"class":210},[33,7736,599],{"class":43},[33,7738,7739,7741,7743,7746,7748,7751,7753,7755,7757,7759,7762],{"class":35,"line":54},[33,7740,124],{"class":39},[33,7742,127],{"class":43},[33,7744,7745],{"class":130},"quantity",[33,7747,134],{"class":43},[33,7749,7750],{"class":130},"setQuantity",[33,7752,140],{"class":43},[33,7754,143],{"class":39},[33,7756,146],{"class":114},[33,7758,149],{"class":43},[33,7760,7761],{"class":130},"1",[33,7763,155],{"class":43},[33,7765,7766],{"class":35,"line":61},[33,7767,58],{"emptyLinePlaceholder":57},[33,7769,7770,7772,7774,7776,7778],{"class":35,"line":68},[33,7771,308],{"class":39},[33,7773,840],{"class":114},[33,7775,149],{"class":43},[33,7777,211],{"class":210},[33,7779,318],{"class":43},[33,7781,7782,7784,7787,7789,7792,7795,7797],{"class":35,"line":74},[33,7783,851],{"class":39},[33,7785,7786],{"class":130}," parsed",[33,7788,287],{"class":39},[33,7790,7791],{"class":114}," parseInt",[33,7793,7794],{"class":43},"(e.target.value, ",[33,7796,895],{"class":130},[33,7798,155],{"class":43},[33,7800,7801,7804],{"class":35,"line":79},[33,7802,7803],{"class":114},"    setQuantity",[33,7805,7806],{"class":43},"(parsed)\n",[33,7808,7809,7812],{"class":35,"line":85},[33,7810,7811],{"class":114},"    onChange",[33,7813,7806],{"class":43},[33,7815,7816],{"class":35,"line":91},[33,7817,348],{"class":43},[33,7819,7820],{"class":35,"line":97},[33,7821,58],{"emptyLinePlaceholder":57},[33,7823,7824,7826,7828,7830,7832,7834,7836,7838,7840,7843,7846,7848,7850,7852,7854],{"class":35,"line":103},[33,7825,161],{"class":39},[33,7827,550],{"class":43},[33,7829,385],{"class":173},[33,7831,388],{"class":114},[33,7833,143],{"class":39},[33,7835,1357],{"class":50},[33,7837,555],{"class":114},[33,7839,143],{"class":39},[33,7841,7842],{"class":43},"{quantity ",[33,7844,7845],{"class":39},"||",[33,7847,5496],{"class":130},[33,7849,1382],{"class":43},[33,7851,643],{"class":114},[33,7853,143],{"class":39},[33,7855,7856],{"class":43},"{handleChange} \u002F>\n",[33,7858,7859],{"class":35,"line":108},[33,7860,238],{"class":43},[7862,7863,7864,7868,7902,7909,8063],"details",{},[7865,7866,7867],"summary",{},"Answer",[5706,7869,7870,7871,7874,7875,7878,7879,7882,7883,7885,7886,7889,7890,7892,7893,7895,7896,7898,7899,7901],{},"Clearing the input produces an empty string, and ",[30,7872,7873],{},"parseInt('', 10)"," returns ",[30,7876,7877],{},"NaN",". ",[30,7880,7881],{},"setQuantity(NaN)"," sets state to ",[30,7884,7877],{},", and on the next render, ",[30,7887,7888],{},"quantity || 0"," evaluates: ",[30,7891,7877],{}," is falsy in JavaScript, so the ",[30,7894,7845],{}," falls through to ",[30,7897,890],{}," — the input is forced back to displaying ",[30,7900,890],{}," on every keystroke that produces an intermediate empty\u002Finvalid value. The user can never clear the field to type a fresh multi-digit number.",[5706,7903,7904,7908],{},[7905,7906,7907],"strong",{},"Fix",": store the raw string, display it directly, and parse only when the value is actually needed:",[24,7910,7912],{"className":26,"code":7911,"language":22,"meta":28,"style":28},"function QuantityInput({ onChange }) {\n  const [rawValue, setRawValue] = useState('1')\n\n  function handleChange(e) {\n    const str = e.target.value\n    setRawValue(str)\n    const parsed = parseInt(str, 10)\n    if (!isNaN(parsed)) onChange(parsed)\n  }\n\n  return \u003Cinput type=\"number\" value={rawValue} onChange={handleChange} \u002F>\n}\n",[30,7913,7914,7926,7953,7957,7969,7981,7989,8006,8024,8028,8032,8059],{"__ignoreMap":28},[33,7915,7916,7918,7920,7922,7924],{"class":35,"line":36},[33,7917,111],{"class":39},[33,7919,7730],{"class":114},[33,7921,593],{"class":43},[33,7923,643],{"class":210},[33,7925,599],{"class":43},[33,7927,7928,7930,7932,7935,7937,7940,7942,7944,7946,7948,7951],{"class":35,"line":54},[33,7929,124],{"class":39},[33,7931,127],{"class":43},[33,7933,7934],{"class":130},"rawValue",[33,7936,134],{"class":43},[33,7938,7939],{"class":130},"setRawValue",[33,7941,140],{"class":43},[33,7943,143],{"class":39},[33,7945,146],{"class":114},[33,7947,149],{"class":43},[33,7949,7950],{"class":50},"'1'",[33,7952,155],{"class":43},[33,7954,7955],{"class":35,"line":61},[33,7956,58],{"emptyLinePlaceholder":57},[33,7958,7959,7961,7963,7965,7967],{"class":35,"line":68},[33,7960,308],{"class":39},[33,7962,840],{"class":114},[33,7964,149],{"class":43},[33,7966,211],{"class":210},[33,7968,318],{"class":43},[33,7970,7971,7973,7976,7978],{"class":35,"line":74},[33,7972,851],{"class":39},[33,7974,7975],{"class":130}," str",[33,7977,287],{"class":39},[33,7979,7980],{"class":43}," e.target.value\n",[33,7982,7983,7986],{"class":35,"line":79},[33,7984,7985],{"class":114},"    setRawValue",[33,7987,7988],{"class":43},"(str)\n",[33,7990,7991,7993,7995,7997,7999,8002,8004],{"class":35,"line":85},[33,7992,851],{"class":39},[33,7994,7786],{"class":130},[33,7996,287],{"class":39},[33,7998,7791],{"class":114},[33,8000,8001],{"class":43},"(str, ",[33,8003,895],{"class":130},[33,8005,155],{"class":43},[33,8007,8008,8010,8012,8014,8017,8020,8022],{"class":35,"line":91},[33,8009,2123],{"class":39},[33,8011,2126],{"class":43},[33,8013,2129],{"class":39},[33,8015,8016],{"class":114},"isNaN",[33,8018,8019],{"class":43},"(parsed)) ",[33,8021,643],{"class":114},[33,8023,7806],{"class":43},[33,8025,8026],{"class":35,"line":97},[33,8027,348],{"class":43},[33,8029,8030],{"class":35,"line":103},[33,8031,58],{"emptyLinePlaceholder":57},[33,8033,8034,8036,8038,8040,8042,8044,8046,8048,8050,8053,8055,8057],{"class":35,"line":108},[33,8035,161],{"class":39},[33,8037,550],{"class":43},[33,8039,385],{"class":173},[33,8041,388],{"class":114},[33,8043,143],{"class":39},[33,8045,1357],{"class":50},[33,8047,555],{"class":114},[33,8049,143],{"class":39},[33,8051,8052],{"class":43},"{rawValue} ",[33,8054,643],{"class":114},[33,8056,143],{"class":39},[33,8058,7856],{"class":43},[33,8060,8061],{"class":35,"line":121},[33,8062,238],{"class":43},[5706,8064,8065,8066,8068,8069,8072,8073,8075,8076,2261],{},"By storing the raw string, the input can display ",[30,8067,152],{}," (empty) while the user types — no ",[30,8070,8071],{},"|| 0"," fallback fighting the user. The numeric parse happens only for the ",[30,8074,643],{}," callback, guarded by ",[30,8077,8016],{},[14,8079,8081],{"id":8080},"key-takeaways","Key Takeaways",[19,8083,8085],{"filename":8084,"language":22},"key_takeaways.js",[24,8086,8088],{"className":26,"code":8087,"language":22,"meta":28,"style":28},"\u002F\u002F 1. Controlled: value={state} + onChange → React owns the value, re-renders per keystroke.\n\u002F\u002F    Uncontrolled: defaultValue + ref → DOM owns the value, read on demand at submit.\n\n\u002F\u002F 2. Always initialize controlled state to a typed empty value ('', 0, false) —\n\u002F\u002F    never undefined\u002Fnull. undefined → uncontrolled first render → warning.\n\n\u002F\u002F 3. File inputs are ALWAYS uncontrolled by browser design. Use ref + .files[0].\n\n\u002F\u002F 4. defaultValue\u002FdefaultChecked apply ONCE at mount — do NOT update on re-render.\n\u002F\u002F    To sync with changing props: remount via key, or switch to controlled.\n\n\u002F\u002F 5. FormData reads all named fields in one call. Use getAll() for multi-value fields.\n\u002F\u002F    Pass FormData directly to fetch body for multipart\u002Fform-data file uploads.\n\n\u002F\u002F 6. 2-3 fields: one useState per field. 5-15: single state object + name-keyed handler.\n\u002F\u002F    Complex (multi-step, dependent validation, async submit): useReducer. See Ch 10.\n\n\u002F\u002F 7. Validate on blur for immediate feedback + validate on submit as a final gate.\n\u002F\u002F    noValidate disables browser popups but NOT CSS :invalid — HTML constraints still apply.\n\n\u002F\u002F 8. Checkboxes\u002Fradios use checked\u002FdefaultChecked, NOT value\u002FdefaultValue.\n\u002F\u002F    \u003Cselect multiple> expects an array of values, not a string.\n",[30,8089,8090,8095,8100,8104,8109,8114,8118,8123,8127,8132,8137,8141,8146,8151,8155,8160,8165,8169,8174,8179,8183,8188],{"__ignoreMap":28},[33,8091,8092],{"class":35,"line":36},[33,8093,8094],{"class":64},"\u002F\u002F 1. Controlled: value={state} + onChange → React owns the value, re-renders per keystroke.\n",[33,8096,8097],{"class":35,"line":54},[33,8098,8099],{"class":64},"\u002F\u002F    Uncontrolled: defaultValue + ref → DOM owns the value, read on demand at submit.\n",[33,8101,8102],{"class":35,"line":61},[33,8103,58],{"emptyLinePlaceholder":57},[33,8105,8106],{"class":35,"line":68},[33,8107,8108],{"class":64},"\u002F\u002F 2. Always initialize controlled state to a typed empty value ('', 0, false) —\n",[33,8110,8111],{"class":35,"line":74},[33,8112,8113],{"class":64},"\u002F\u002F    never undefined\u002Fnull. undefined → uncontrolled first render → warning.\n",[33,8115,8116],{"class":35,"line":79},[33,8117,58],{"emptyLinePlaceholder":57},[33,8119,8120],{"class":35,"line":85},[33,8121,8122],{"class":64},"\u002F\u002F 3. File inputs are ALWAYS uncontrolled by browser design. Use ref + .files[0].\n",[33,8124,8125],{"class":35,"line":91},[33,8126,58],{"emptyLinePlaceholder":57},[33,8128,8129],{"class":35,"line":97},[33,8130,8131],{"class":64},"\u002F\u002F 4. defaultValue\u002FdefaultChecked apply ONCE at mount — do NOT update on re-render.\n",[33,8133,8134],{"class":35,"line":103},[33,8135,8136],{"class":64},"\u002F\u002F    To sync with changing props: remount via key, or switch to controlled.\n",[33,8138,8139],{"class":35,"line":108},[33,8140,58],{"emptyLinePlaceholder":57},[33,8142,8143],{"class":35,"line":121},[33,8144,8145],{"class":64},"\u002F\u002F 5. FormData reads all named fields in one call. Use getAll() for multi-value fields.\n",[33,8147,8148],{"class":35,"line":158},[33,8149,8150],{"class":64},"\u002F\u002F    Pass FormData directly to fetch body for multipart\u002Fform-data file uploads.\n",[33,8152,8153],{"class":35,"line":167},[33,8154,58],{"emptyLinePlaceholder":57},[33,8156,8157],{"class":35,"line":177},[33,8158,8159],{"class":64},"\u002F\u002F 6. 2-3 fields: one useState per field. 5-15: single state object + name-keyed handler.\n",[33,8161,8162],{"class":35,"line":188},[33,8163,8164],{"class":64},"\u002F\u002F    Complex (multi-step, dependent validation, async submit): useReducer. See Ch 10.\n",[33,8166,8167],{"class":35,"line":199},[33,8168,58],{"emptyLinePlaceholder":57},[33,8170,8171],{"class":35,"line":223},[33,8172,8173],{"class":64},"\u002F\u002F 7. Validate on blur for immediate feedback + validate on submit as a final gate.\n",[33,8175,8176],{"class":35,"line":229},[33,8177,8178],{"class":64},"\u002F\u002F    noValidate disables browser popups but NOT CSS :invalid — HTML constraints still apply.\n",[33,8180,8181],{"class":35,"line":235},[33,8182,58],{"emptyLinePlaceholder":57},[33,8184,8185],{"class":35,"line":241},[33,8186,8187],{"class":64},"\u002F\u002F 8. Checkboxes\u002Fradios use checked\u002FdefaultChecked, NOT value\u002FdefaultValue.\n",[33,8189,8190],{"class":35,"line":246},[33,8191,8192],{"class":64},"\u002F\u002F    \u003Cselect multiple> expects an array of values, not a string.\n",[8194,8195,8196],"style",{},"html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sk71V, html code.shiki .sk71V{--shiki-default:#22863A;--shiki-github-dark:#85E89D}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .svAP2, html code.shiki .svAP2{--shiki-default:#032F62;--shiki-github-dark:#DBEDFF}html pre.shiki code .snRuI, html code.shiki .snRuI{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-github-dark:#85E89D;--shiki-github-dark-font-weight:bold}",{"title":28,"searchDepth":54,"depth":54,"links":8198},[8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212],{"id":16,"depth":54,"text":17},{"id":455,"depth":54,"text":456},{"id":757,"depth":54,"text":758},{"id":1401,"depth":54,"text":1402},{"id":1989,"depth":54,"text":1990},{"id":2833,"depth":54,"text":2834},{"id":3253,"depth":54,"text":3254},{"id":4034,"depth":54,"text":4035},{"id":4523,"depth":54,"text":4524},{"id":6244,"depth":54,"text":6245},{"id":7448,"depth":54,"text":7449},{"id":7564,"depth":54,"text":7565},{"id":7709,"depth":54,"text":7710},{"id":8080,"depth":54,"text":8081},"Controlled vs uncontrolled inputs, the controlled input loop, file inputs, defaultValues, FormData submission, validation patterns, multi-field forms with useReducer, uncontrolled with useRef. Code-first reference for mid-to-senior React engineers.","md",{},"\u002Freact\u002F14-forms-controlled-and-uncontrolled",{"title":5,"description":8213},"react\u002F14-forms-controlled-and-uncontrolled","4vnmlUUvddtahWvrvlzp-aqoyaiJX9fecdyXDqsyzPg",1789924652273]