[{"data":1,"prerenderedAt":7185},["ShallowReactive",2],{"page-\u002Freact\u002F12-conditional-rendering-patterns":3},{"id":4,"title":5,"body":6,"description":7178,"extension":7179,"meta":7180,"navigation":64,"path":7181,"seo":7182,"stem":7183,"__hash__":7184},"content\u002Freact\u002F12-conditional-rendering-patterns.md","12 — Conditional Rendering Patterns",{"type":7,"value":8,"toc":7162},"minimark",[9,13,18,471,475,1045,1049,1749,1754,2091,2095,2925,2929,3912,3916,5312,5316,6155,6159,6538,6542,6655,6659,6791,6795,6801,6935,7048,7052,7159],[10,11,5],"h1",{"id":12},"_12-conditional-rendering-patterns",[14,15,17],"h2",{"id":16},"the-core-mechanisms","The Core Mechanisms",[19,20,23],"code-wrapper",{"filename":21,"language":22},"core_mechanics.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","\u002F\u002F JSX renders any expression that evaluates to: React element | string | number | null | false | undefined | true\n\u002F\u002F React DOM renders: elements, strings, numbers\n\u002F\u002F React DOM ignores: null, false, undefined, true (renders nothing, no DOM node)\n\u002F\u002F CAVEAT: 0 (zero) IS rendered — this is the most common && gotcha (see below)\n\nimport React, { useState, useEffect, Fragment } from 'react'\n\n\u002F\u002F ── 1. Ternary: two mutually exclusive branches ──\nfunction AuthToggle({ isAuthenticated }) {\n  return isAuthenticated ? \u003CLogoutButton \u002F> : \u003CSignInButton \u002F>\n}\n\n\u002F\u002F ── 2. &&: one branch or nothing (conditional inclusion) ──\nfunction NewBadge({ isNew }) {\n  return (\n    \u003Cdiv>\n      \u003Cspan>Product Name\u003C\u002Fspan>\n      {isNew && \u003Cspan className=\"badge\">New\u003C\u002Fspan>}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ── 3. IIFE: inline computation that returns JSX (rare but real) ──\nfunction DynamicHeader({ type, data }) {\n  return (\n    \u003Cheader>\n      {(() => {\n        switch (type) {\n          case 'user':   return \u003CUserHeader user={data} \u002F>\n          case 'org':    return \u003COrgHeader org={data} \u002F>\n          case 'system': return \u003CSystemHeader \u002F>\n          default:       return \u003CDefaultHeader \u002F>\n        }\n      })()}\n    \u003C\u002Fheader>\n  )\n  \u002F\u002F IIFE is useful when you need a full block scope (let\u002Fconst, switch, try\u002Fcatch)\n  \u002F\u002F inside JSX. Overuse hurts readability — extract to a variable or sub-component instead.\n}\n","",[30,31,32,41,47,53,59,66,84,89,95,115,148,154,159,165,180,188,201,216,246,256,262,267,272,278,299,306,316,328,337,365,390,410,428,434,440,449,454,460,466],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sdCPZ","\u002F\u002F JSX renders any expression that evaluates to: React element | string | number | null | false | undefined | true\n",[33,42,44],{"class":35,"line":43},2,[33,45,46],{"class":39},"\u002F\u002F React DOM renders: elements, strings, numbers\n",[33,48,50],{"class":35,"line":49},3,[33,51,52],{"class":39},"\u002F\u002F React DOM ignores: null, false, undefined, true (renders nothing, no DOM node)\n",[33,54,56],{"class":35,"line":55},4,[33,57,58],{"class":39},"\u002F\u002F CAVEAT: 0 (zero) IS rendered — this is the most common && gotcha (see below)\n",[33,60,62],{"class":35,"line":61},5,[33,63,65],{"emptyLinePlaceholder":64},true,"\n",[33,67,69,73,77,80],{"class":35,"line":68},6,[33,70,72],{"class":71},"svdQ7","import",[33,74,76],{"class":75},"ssxIu"," React, { useState, useEffect, Fragment } ",[33,78,79],{"class":71},"from",[33,81,83],{"class":82},"sJ6F3"," 'react'\n",[33,85,87],{"class":35,"line":86},7,[33,88,65],{"emptyLinePlaceholder":64},[33,90,92],{"class":35,"line":91},8,[33,93,94],{"class":39},"\u002F\u002F ── 1. Ternary: two mutually exclusive branches ──\n",[33,96,98,101,105,108,112],{"class":35,"line":97},9,[33,99,100],{"class":71},"function",[33,102,104],{"class":103},"sIsaT"," AuthToggle",[33,106,107],{"class":75},"({ ",[33,109,111],{"class":110},"sCrzJ","isAuthenticated",[33,113,114],{"class":75}," }) {\n",[33,116,118,121,124,127,130,134,137,140,142,145],{"class":35,"line":117},10,[33,119,120],{"class":71},"  return",[33,122,123],{"class":75}," isAuthenticated ",[33,125,126],{"class":71},"?",[33,128,129],{"class":75}," \u003C",[33,131,133],{"class":132},"snvgF","LogoutButton",[33,135,136],{"class":75}," \u002F> ",[33,138,139],{"class":71},":",[33,141,129],{"class":75},[33,143,144],{"class":132},"SignInButton",[33,146,147],{"class":75}," \u002F>\n",[33,149,151],{"class":35,"line":150},11,[33,152,153],{"class":75},"}\n",[33,155,157],{"class":35,"line":156},12,[33,158,65],{"emptyLinePlaceholder":64},[33,160,162],{"class":35,"line":161},13,[33,163,164],{"class":39},"\u002F\u002F ── 2. &&: one branch or nothing (conditional inclusion) ──\n",[33,166,168,170,173,175,178],{"class":35,"line":167},14,[33,169,100],{"class":71},[33,171,172],{"class":103}," NewBadge",[33,174,107],{"class":75},[33,176,177],{"class":110},"isNew",[33,179,114],{"class":75},[33,181,183,185],{"class":35,"line":182},15,[33,184,120],{"class":71},[33,186,187],{"class":75}," (\n",[33,189,191,194,198],{"class":35,"line":190},16,[33,192,193],{"class":75},"    \u003C",[33,195,197],{"class":196},"sk71V","div",[33,199,200],{"class":75},">\n",[33,202,204,207,209,212,214],{"class":35,"line":203},17,[33,205,206],{"class":75},"      \u003C",[33,208,33],{"class":196},[33,210,211],{"class":75},">Product Name\u003C\u002F",[33,213,33],{"class":196},[33,215,200],{"class":75},[33,217,219,222,225,227,229,232,235,238,241,243],{"class":35,"line":218},18,[33,220,221],{"class":75},"      {isNew ",[33,223,224],{"class":71},"&&",[33,226,129],{"class":75},[33,228,33],{"class":196},[33,230,231],{"class":103}," className",[33,233,234],{"class":71},"=",[33,236,237],{"class":82},"\"badge\"",[33,239,240],{"class":75},">New\u003C\u002F",[33,242,33],{"class":196},[33,244,245],{"class":75},">}\n",[33,247,249,252,254],{"class":35,"line":248},19,[33,250,251],{"class":75},"    \u003C\u002F",[33,253,197],{"class":196},[33,255,200],{"class":75},[33,257,259],{"class":35,"line":258},20,[33,260,261],{"class":75},"  )\n",[33,263,265],{"class":35,"line":264},21,[33,266,153],{"class":75},[33,268,270],{"class":35,"line":269},22,[33,271,65],{"emptyLinePlaceholder":64},[33,273,275],{"class":35,"line":274},23,[33,276,277],{"class":39},"\u002F\u002F ── 3. IIFE: inline computation that returns JSX (rare but real) ──\n",[33,279,281,283,286,288,291,294,297],{"class":35,"line":280},24,[33,282,100],{"class":71},[33,284,285],{"class":103}," DynamicHeader",[33,287,107],{"class":75},[33,289,290],{"class":110},"type",[33,292,293],{"class":75},", ",[33,295,296],{"class":110},"data",[33,298,114],{"class":75},[33,300,302,304],{"class":35,"line":301},25,[33,303,120],{"class":71},[33,305,187],{"class":75},[33,307,309,311,314],{"class":35,"line":308},26,[33,310,193],{"class":75},[33,312,313],{"class":196},"header",[33,315,200],{"class":75},[33,317,319,322,325],{"class":35,"line":318},27,[33,320,321],{"class":75},"      {(() ",[33,323,324],{"class":71},"=>",[33,326,327],{"class":75}," {\n",[33,329,331,334],{"class":35,"line":330},28,[33,332,333],{"class":71},"        switch",[33,335,336],{"class":75}," (type) {\n",[33,338,340,343,346,349,352,354,357,360,362],{"class":35,"line":339},29,[33,341,342],{"class":71},"          case",[33,344,345],{"class":82}," 'user'",[33,347,348],{"class":75},":   ",[33,350,351],{"class":71},"return",[33,353,129],{"class":75},[33,355,356],{"class":132},"UserHeader",[33,358,359],{"class":103}," user",[33,361,234],{"class":71},[33,363,364],{"class":75},"{data} \u002F>\n",[33,366,368,370,373,376,378,380,383,386,388],{"class":35,"line":367},30,[33,369,342],{"class":71},[33,371,372],{"class":82}," 'org'",[33,374,375],{"class":75},":    ",[33,377,351],{"class":71},[33,379,129],{"class":75},[33,381,382],{"class":132},"OrgHeader",[33,384,385],{"class":103}," org",[33,387,234],{"class":71},[33,389,364],{"class":75},[33,391,393,395,398,401,403,405,408],{"class":35,"line":392},31,[33,394,342],{"class":71},[33,396,397],{"class":82}," 'system'",[33,399,400],{"class":75},": ",[33,402,351],{"class":71},[33,404,129],{"class":75},[33,406,407],{"class":132},"SystemHeader",[33,409,147],{"class":75},[33,411,413,416,419,421,423,426],{"class":35,"line":412},32,[33,414,415],{"class":71},"          default",[33,417,418],{"class":75},":       ",[33,420,351],{"class":71},[33,422,129],{"class":75},[33,424,425],{"class":132},"DefaultHeader",[33,427,147],{"class":75},[33,429,431],{"class":35,"line":430},33,[33,432,433],{"class":75},"        }\n",[33,435,437],{"class":35,"line":436},34,[33,438,439],{"class":75},"      })()}\n",[33,441,443,445,447],{"class":35,"line":442},35,[33,444,251],{"class":75},[33,446,313],{"class":196},[33,448,200],{"class":75},[33,450,452],{"class":35,"line":451},36,[33,453,261],{"class":75},[33,455,457],{"class":35,"line":456},37,[33,458,459],{"class":39},"  \u002F\u002F IIFE is useful when you need a full block scope (let\u002Fconst, switch, try\u002Fcatch)\n",[33,461,463],{"class":35,"line":462},38,[33,464,465],{"class":39},"  \u002F\u002F inside JSX. Overuse hurts readability — extract to a variable or sub-component instead.\n",[33,467,469],{"class":35,"line":468},39,[33,470,153],{"class":75},[14,472,474],{"id":473},"the-zero-rendering-gotcha","The Zero-Rendering Gotcha (&&)",[19,476,478],{"filename":477,"language":22},"zero_gotcha.js",[24,479,481],{"className":26,"code":480,"language":22,"meta":28,"style":28},"\u002F\u002F WRONG: renders \"0\" into the DOM when items.length === 0\nfunction CartCount({ items }) {\n  return (\n    \u003Cdiv>\n      {items.length && \u003Cspan>{items.length} items in cart\u003C\u002Fspan>}\n    \u003C\u002Fdiv>\n  )\n  \u002F\u002F When items = [], items.length is 0 (a number). 0 is NOT ignored by React —\n  \u002F\u002F React renders it as the text \"0\". Users see a stray \"0\" with no \u003Cspan>.\n}\n\n\u002F\u002F FIX 1: explicit boolean coercion\nfunction CartCountFixed1({ items }) {\n  return (\n    \u003Cdiv>\n      {items.length > 0 && \u003Cspan>{items.length} items in cart\u003C\u002Fspan>}\n      \u002F\u002F items.length > 0 evaluates to true\u002Ffalse — false renders nothing.\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F FIX 2: ternary with explicit null\nfunction CartCountFixed2({ items }) {\n  return (\n    \u003Cdiv>\n      {items.length > 0 ? (\n        \u003Cspan>{items.length} items in cart\u003C\u002Fspan>\n      ) : null}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F FIX 3: render the count, but handle the empty case explicitly\nfunction CartCountFixed3({ items }) {\n  return (\n    \u003Cdiv>\n      {items.length > 0 ? (\n        \u003Cspan>{items.length} items in cart\u003C\u002Fspan>\n      ) : (\n        \u003Cspan className=\"empty\">Your cart is empty\u003C\u002Fspan>\n      )}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F WORST CASE: array of numbers with filter + &&\nfunction FilteredList({ items }) {\n  const filtered = items.filter(x => x > 10)\n  return (\n    \u003Cul>\n      {filtered.map(x => \u003Cli key={x}>{x}\u003C\u002Fli>)}\n      {filtered.length === 0 && \u003Cli>No results\u003C\u002Fli>}\n      \u002F\u002F If filtered = [0], filter returns [] → filtered.length = 0 → 0 && \u003Cli> → renders \"0\"\n      \u002F\u002F Always use === 0 (explicit comparison) or > 0, never bare .length with &&\n    \u003C\u002Ful>\n  )\n}\n",[30,482,483,488,502,508,516,543,551,555,560,565,569,573,578,591,597,605,633,638,646,650,654,658,663,676,682,690,705,722,734,742,746,750,754,759,772,778,786,800,816,824,845,851,860,865,870,875,881,895,934,941,951,984,1009,1020,1026,1035,1040],{"__ignoreMap":28},[33,484,485],{"class":35,"line":36},[33,486,487],{"class":39},"\u002F\u002F WRONG: renders \"0\" into the DOM when items.length === 0\n",[33,489,490,492,495,497,500],{"class":35,"line":43},[33,491,100],{"class":71},[33,493,494],{"class":103}," CartCount",[33,496,107],{"class":75},[33,498,499],{"class":110},"items",[33,501,114],{"class":75},[33,503,504,506],{"class":35,"line":49},[33,505,120],{"class":71},[33,507,187],{"class":75},[33,509,510,512,514],{"class":35,"line":55},[33,511,193],{"class":75},[33,513,197],{"class":196},[33,515,200],{"class":75},[33,517,518,521,524,527,529,531,534,536,539,541],{"class":35,"line":61},[33,519,520],{"class":75},"      {items.",[33,522,523],{"class":132},"length",[33,525,526],{"class":71}," &&",[33,528,129],{"class":75},[33,530,33],{"class":196},[33,532,533],{"class":75},">{items.",[33,535,523],{"class":132},[33,537,538],{"class":75},"} items in cart\u003C\u002F",[33,540,33],{"class":196},[33,542,245],{"class":75},[33,544,545,547,549],{"class":35,"line":68},[33,546,251],{"class":75},[33,548,197],{"class":196},[33,550,200],{"class":75},[33,552,553],{"class":35,"line":86},[33,554,261],{"class":75},[33,556,557],{"class":35,"line":91},[33,558,559],{"class":39},"  \u002F\u002F When items = [], items.length is 0 (a number). 0 is NOT ignored by React —\n",[33,561,562],{"class":35,"line":97},[33,563,564],{"class":39},"  \u002F\u002F React renders it as the text \"0\". Users see a stray \"0\" with no \u003Cspan>.\n",[33,566,567],{"class":35,"line":117},[33,568,153],{"class":75},[33,570,571],{"class":35,"line":150},[33,572,65],{"emptyLinePlaceholder":64},[33,574,575],{"class":35,"line":156},[33,576,577],{"class":39},"\u002F\u002F FIX 1: explicit boolean coercion\n",[33,579,580,582,585,587,589],{"class":35,"line":161},[33,581,100],{"class":71},[33,583,584],{"class":103}," CartCountFixed1",[33,586,107],{"class":75},[33,588,499],{"class":110},[33,590,114],{"class":75},[33,592,593,595],{"class":35,"line":167},[33,594,120],{"class":71},[33,596,187],{"class":75},[33,598,599,601,603],{"class":35,"line":182},[33,600,193],{"class":75},[33,602,197],{"class":196},[33,604,200],{"class":75},[33,606,607,609,611,614,617,619,621,623,625,627,629,631],{"class":35,"line":190},[33,608,520],{"class":75},[33,610,523],{"class":132},[33,612,613],{"class":71}," >",[33,615,616],{"class":132}," 0",[33,618,526],{"class":71},[33,620,129],{"class":75},[33,622,33],{"class":196},[33,624,533],{"class":75},[33,626,523],{"class":132},[33,628,538],{"class":75},[33,630,33],{"class":196},[33,632,245],{"class":75},[33,634,635],{"class":35,"line":203},[33,636,637],{"class":75},"      \u002F\u002F items.length > 0 evaluates to true\u002Ffalse — false renders nothing.\n",[33,639,640,642,644],{"class":35,"line":218},[33,641,251],{"class":75},[33,643,197],{"class":196},[33,645,200],{"class":75},[33,647,648],{"class":35,"line":248},[33,649,261],{"class":75},[33,651,652],{"class":35,"line":258},[33,653,153],{"class":75},[33,655,656],{"class":35,"line":264},[33,657,65],{"emptyLinePlaceholder":64},[33,659,660],{"class":35,"line":269},[33,661,662],{"class":39},"\u002F\u002F FIX 2: ternary with explicit null\n",[33,664,665,667,670,672,674],{"class":35,"line":274},[33,666,100],{"class":71},[33,668,669],{"class":103}," CartCountFixed2",[33,671,107],{"class":75},[33,673,499],{"class":110},[33,675,114],{"class":75},[33,677,678,680],{"class":35,"line":280},[33,679,120],{"class":71},[33,681,187],{"class":75},[33,683,684,686,688],{"class":35,"line":301},[33,685,193],{"class":75},[33,687,197],{"class":196},[33,689,200],{"class":75},[33,691,692,694,696,698,700,703],{"class":35,"line":308},[33,693,520],{"class":75},[33,695,523],{"class":132},[33,697,613],{"class":71},[33,699,616],{"class":132},[33,701,702],{"class":71}," ?",[33,704,187],{"class":75},[33,706,707,710,712,714,716,718,720],{"class":35,"line":318},[33,708,709],{"class":75},"        \u003C",[33,711,33],{"class":196},[33,713,533],{"class":75},[33,715,523],{"class":132},[33,717,538],{"class":75},[33,719,33],{"class":196},[33,721,200],{"class":75},[33,723,724,727,729,732],{"class":35,"line":330},[33,725,726],{"class":75},"      ) ",[33,728,139],{"class":71},[33,730,731],{"class":132}," null",[33,733,153],{"class":75},[33,735,736,738,740],{"class":35,"line":339},[33,737,251],{"class":75},[33,739,197],{"class":196},[33,741,200],{"class":75},[33,743,744],{"class":35,"line":367},[33,745,261],{"class":75},[33,747,748],{"class":35,"line":392},[33,749,153],{"class":75},[33,751,752],{"class":35,"line":412},[33,753,65],{"emptyLinePlaceholder":64},[33,755,756],{"class":35,"line":430},[33,757,758],{"class":39},"\u002F\u002F FIX 3: render the count, but handle the empty case explicitly\n",[33,760,761,763,766,768,770],{"class":35,"line":436},[33,762,100],{"class":71},[33,764,765],{"class":103}," CartCountFixed3",[33,767,107],{"class":75},[33,769,499],{"class":110},[33,771,114],{"class":75},[33,773,774,776],{"class":35,"line":442},[33,775,120],{"class":71},[33,777,187],{"class":75},[33,779,780,782,784],{"class":35,"line":451},[33,781,193],{"class":75},[33,783,197],{"class":196},[33,785,200],{"class":75},[33,787,788,790,792,794,796,798],{"class":35,"line":456},[33,789,520],{"class":75},[33,791,523],{"class":132},[33,793,613],{"class":71},[33,795,616],{"class":132},[33,797,702],{"class":71},[33,799,187],{"class":75},[33,801,802,804,806,808,810,812,814],{"class":35,"line":462},[33,803,709],{"class":75},[33,805,33],{"class":196},[33,807,533],{"class":75},[33,809,523],{"class":132},[33,811,538],{"class":75},[33,813,33],{"class":196},[33,815,200],{"class":75},[33,817,818,820,822],{"class":35,"line":468},[33,819,726],{"class":75},[33,821,139],{"class":71},[33,823,187],{"class":75},[33,825,827,829,831,833,835,838,841,843],{"class":35,"line":826},40,[33,828,709],{"class":75},[33,830,33],{"class":196},[33,832,231],{"class":103},[33,834,234],{"class":71},[33,836,837],{"class":82},"\"empty\"",[33,839,840],{"class":75},">Your cart is empty\u003C\u002F",[33,842,33],{"class":196},[33,844,200],{"class":75},[33,846,848],{"class":35,"line":847},41,[33,849,850],{"class":75},"      )}\n",[33,852,854,856,858],{"class":35,"line":853},42,[33,855,251],{"class":75},[33,857,197],{"class":196},[33,859,200],{"class":75},[33,861,863],{"class":35,"line":862},43,[33,864,261],{"class":75},[33,866,868],{"class":35,"line":867},44,[33,869,153],{"class":75},[33,871,873],{"class":35,"line":872},45,[33,874,65],{"emptyLinePlaceholder":64},[33,876,878],{"class":35,"line":877},46,[33,879,880],{"class":39},"\u002F\u002F WORST CASE: array of numbers with filter + &&\n",[33,882,884,886,889,891,893],{"class":35,"line":883},47,[33,885,100],{"class":71},[33,887,888],{"class":103}," FilteredList",[33,890,107],{"class":75},[33,892,499],{"class":110},[33,894,114],{"class":75},[33,896,898,901,904,907,910,913,916,919,922,925,928,931],{"class":35,"line":897},48,[33,899,900],{"class":71},"  const",[33,902,903],{"class":132}," filtered",[33,905,906],{"class":71}," =",[33,908,909],{"class":75}," items.",[33,911,912],{"class":103},"filter",[33,914,915],{"class":75},"(",[33,917,918],{"class":110},"x",[33,920,921],{"class":71}," =>",[33,923,924],{"class":75}," x ",[33,926,927],{"class":71},">",[33,929,930],{"class":132}," 10",[33,932,933],{"class":75},")\n",[33,935,937,939],{"class":35,"line":936},49,[33,938,120],{"class":71},[33,940,187],{"class":75},[33,942,944,946,949],{"class":35,"line":943},50,[33,945,193],{"class":75},[33,947,948],{"class":196},"ul",[33,950,200],{"class":75},[33,952,954,957,960,962,964,966,968,971,974,976,979,981],{"class":35,"line":953},51,[33,955,956],{"class":75},"      {filtered.",[33,958,959],{"class":103},"map",[33,961,915],{"class":75},[33,963,918],{"class":110},[33,965,921],{"class":71},[33,967,129],{"class":75},[33,969,970],{"class":196},"li",[33,972,973],{"class":103}," key",[33,975,234],{"class":71},[33,977,978],{"class":75},"{x}>{x}\u003C\u002F",[33,980,970],{"class":196},[33,982,983],{"class":75},">)}\n",[33,985,987,989,991,994,996,998,1000,1002,1005,1007],{"class":35,"line":986},52,[33,988,956],{"class":75},[33,990,523],{"class":132},[33,992,993],{"class":71}," ===",[33,995,616],{"class":132},[33,997,526],{"class":71},[33,999,129],{"class":75},[33,1001,970],{"class":196},[33,1003,1004],{"class":75},">No results\u003C\u002F",[33,1006,970],{"class":196},[33,1008,245],{"class":75},[33,1010,1012,1015,1017],{"class":35,"line":1011},53,[33,1013,1014],{"class":75},"      \u002F\u002F If filtered = [0], filter returns [] → filtered.length = 0 → 0 && \u003C",[33,1016,970],{"class":196},[33,1018,1019],{"class":75},"> → renders \"0\"\n",[33,1021,1023],{"class":35,"line":1022},54,[33,1024,1025],{"class":75},"      \u002F\u002F Always use === 0 (explicit comparison) or > 0, never bare .length with &&\n",[33,1027,1029,1031,1033],{"class":35,"line":1028},55,[33,1030,251],{"class":75},[33,1032,948],{"class":196},[33,1034,200],{"class":75},[33,1036,1038],{"class":35,"line":1037},56,[33,1039,261],{"class":75},[33,1041,1043],{"class":35,"line":1042},57,[33,1044,153],{"class":75},[14,1046,1048],{"id":1047},"early-returns-whole-component-branches","Early Returns: Whole-Component Branches",[19,1050,1052],{"filename":1051,"language":22},"early_returns.js",[24,1053,1055],{"className":26,"code":1054,"language":22,"meta":28,"style":28},"import { useState, useEffect } from 'react'\n\n\u002F\u002F ANTI-PATTERN: nested ternaries for whole-component output — unreadable at 3+ branches\nfunction UserProfileBad({ status, user, error }) {\n  return status === 'loading' ? (\n    \u003CSpinner \u002F>\n  ) : status === 'error' ? (\n    \u003CErrorMessage error={error} \u002F>\n  ) : status === 'success' ? (\n    \u003CProfileCard user={user} \u002F>\n  ) : null\n  \u002F\u002F Each additional branch nests deeper. Adding \"empty\" state requires another ? : layer.\n}\n\n\u002F\u002F CORRECT: early returns — flat, scannable, each guard is a standalone clause\nfunction UserProfileGood({ status, user, error }) {\n  if (status === 'loading') return \u003CSpinner \u002F>\n  if (status === 'error')   return \u003CErrorMessage error={error} \u002F>\n  if (status === 'success') return \u003CProfileCard user={user} \u002F>\n  return null  \u002F\u002F idle \u002F unknown status\n}\n\n\u002F\u002F COMPLEX: multi-state with per-branch data preparation\nfunction SearchResults({ status, results, error, query, onRetry }) {\n  \u002F\u002F All hooks MUST come before any early return (Rules of Hooks — Ch 11)\n  const [retryCount, setRetryCount] = useState(0)\n\n  useEffect(() => {\n    if (status === 'error') setRetryCount(0)\n  }, [status])\n\n  if (status === 'idle')    return \u003CSearchPrompt query={query} \u002F>\n  if (status === 'loading') return \u003CSkeletonLoader count={5} \u002F>\n  if (status === 'error')   return \u003CErrorState error={error} onRetry={() => { setRetryCount(c => c + 1); onRetry() }} retryCount={retryCount} \u002F>\n  if (status === 'success' && results.length === 0) {\n    return \u003CEmptyState message={`No results for \"${query}\"`} \u002F>\n  }\n  if (status === 'success') {\n    return (\n      \u003Cul>\n        {results.map(r => (\n          \u003Cli key={r.id}>\n            \u003CResultCard data={r} \u002F>\n          \u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    )\n  }\n  return null\n}\n",[30,1056,1057,1068,1072,1077,1101,1118,1127,1145,1160,1177,1191,1200,1205,1209,1213,1218,1239,1262,1287,1311,1320,1324,1328,1333,1365,1370,1400,1404,1416,1437,1442,1446,1475,1508,1579,1603,1630,1635,1647,1653,1661,1677,1691,1707,1716,1721,1730,1735,1739,1745],{"__ignoreMap":28},[33,1058,1059,1061,1064,1066],{"class":35,"line":36},[33,1060,72],{"class":71},[33,1062,1063],{"class":75}," { useState, useEffect } ",[33,1065,79],{"class":71},[33,1067,83],{"class":82},[33,1069,1070],{"class":35,"line":43},[33,1071,65],{"emptyLinePlaceholder":64},[33,1073,1074],{"class":35,"line":49},[33,1075,1076],{"class":39},"\u002F\u002F ANTI-PATTERN: nested ternaries for whole-component output — unreadable at 3+ branches\n",[33,1078,1079,1081,1084,1086,1089,1091,1094,1096,1099],{"class":35,"line":55},[33,1080,100],{"class":71},[33,1082,1083],{"class":103}," UserProfileBad",[33,1085,107],{"class":75},[33,1087,1088],{"class":110},"status",[33,1090,293],{"class":75},[33,1092,1093],{"class":110},"user",[33,1095,293],{"class":75},[33,1097,1098],{"class":110},"error",[33,1100,114],{"class":75},[33,1102,1103,1105,1108,1111,1114,1116],{"class":35,"line":61},[33,1104,120],{"class":71},[33,1106,1107],{"class":75}," status ",[33,1109,1110],{"class":71},"===",[33,1112,1113],{"class":82}," 'loading'",[33,1115,702],{"class":71},[33,1117,187],{"class":75},[33,1119,1120,1122,1125],{"class":35,"line":68},[33,1121,193],{"class":75},[33,1123,1124],{"class":132},"Spinner",[33,1126,147],{"class":75},[33,1128,1129,1132,1134,1136,1138,1141,1143],{"class":35,"line":86},[33,1130,1131],{"class":75},"  ) ",[33,1133,139],{"class":71},[33,1135,1107],{"class":75},[33,1137,1110],{"class":71},[33,1139,1140],{"class":82}," 'error'",[33,1142,702],{"class":71},[33,1144,187],{"class":75},[33,1146,1147,1149,1152,1155,1157],{"class":35,"line":91},[33,1148,193],{"class":75},[33,1150,1151],{"class":132},"ErrorMessage",[33,1153,1154],{"class":103}," error",[33,1156,234],{"class":71},[33,1158,1159],{"class":75},"{error} \u002F>\n",[33,1161,1162,1164,1166,1168,1170,1173,1175],{"class":35,"line":97},[33,1163,1131],{"class":75},[33,1165,139],{"class":71},[33,1167,1107],{"class":75},[33,1169,1110],{"class":71},[33,1171,1172],{"class":82}," 'success'",[33,1174,702],{"class":71},[33,1176,187],{"class":75},[33,1178,1179,1181,1184,1186,1188],{"class":35,"line":117},[33,1180,193],{"class":75},[33,1182,1183],{"class":132},"ProfileCard",[33,1185,359],{"class":103},[33,1187,234],{"class":71},[33,1189,1190],{"class":75},"{user} \u002F>\n",[33,1192,1193,1195,1197],{"class":35,"line":150},[33,1194,1131],{"class":75},[33,1196,139],{"class":71},[33,1198,1199],{"class":132}," null\n",[33,1201,1202],{"class":35,"line":156},[33,1203,1204],{"class":39},"  \u002F\u002F Each additional branch nests deeper. Adding \"empty\" state requires another ? : layer.\n",[33,1206,1207],{"class":35,"line":161},[33,1208,153],{"class":75},[33,1210,1211],{"class":35,"line":167},[33,1212,65],{"emptyLinePlaceholder":64},[33,1214,1215],{"class":35,"line":182},[33,1216,1217],{"class":39},"\u002F\u002F CORRECT: early returns — flat, scannable, each guard is a standalone clause\n",[33,1219,1220,1222,1225,1227,1229,1231,1233,1235,1237],{"class":35,"line":190},[33,1221,100],{"class":71},[33,1223,1224],{"class":103}," UserProfileGood",[33,1226,107],{"class":75},[33,1228,1088],{"class":110},[33,1230,293],{"class":75},[33,1232,1093],{"class":110},[33,1234,293],{"class":75},[33,1236,1098],{"class":110},[33,1238,114],{"class":75},[33,1240,1241,1244,1247,1249,1251,1254,1256,1258,1260],{"class":35,"line":203},[33,1242,1243],{"class":71},"  if",[33,1245,1246],{"class":75}," (status ",[33,1248,1110],{"class":71},[33,1250,1113],{"class":82},[33,1252,1253],{"class":75},") ",[33,1255,351],{"class":71},[33,1257,129],{"class":75},[33,1259,1124],{"class":132},[33,1261,147],{"class":75},[33,1263,1264,1266,1268,1270,1272,1275,1277,1279,1281,1283,1285],{"class":35,"line":218},[33,1265,1243],{"class":71},[33,1267,1246],{"class":75},[33,1269,1110],{"class":71},[33,1271,1140],{"class":82},[33,1273,1274],{"class":75},")   ",[33,1276,351],{"class":71},[33,1278,129],{"class":75},[33,1280,1151],{"class":132},[33,1282,1154],{"class":103},[33,1284,234],{"class":71},[33,1286,1159],{"class":75},[33,1288,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309],{"class":35,"line":248},[33,1290,1243],{"class":71},[33,1292,1246],{"class":75},[33,1294,1110],{"class":71},[33,1296,1172],{"class":82},[33,1298,1253],{"class":75},[33,1300,351],{"class":71},[33,1302,129],{"class":75},[33,1304,1183],{"class":132},[33,1306,359],{"class":103},[33,1308,234],{"class":71},[33,1310,1190],{"class":75},[33,1312,1313,1315,1317],{"class":35,"line":258},[33,1314,120],{"class":71},[33,1316,731],{"class":132},[33,1318,1319],{"class":39},"  \u002F\u002F idle \u002F unknown status\n",[33,1321,1322],{"class":35,"line":264},[33,1323,153],{"class":75},[33,1325,1326],{"class":35,"line":269},[33,1327,65],{"emptyLinePlaceholder":64},[33,1329,1330],{"class":35,"line":274},[33,1331,1332],{"class":39},"\u002F\u002F COMPLEX: multi-state with per-branch data preparation\n",[33,1334,1335,1337,1340,1342,1344,1346,1349,1351,1353,1355,1358,1360,1363],{"class":35,"line":280},[33,1336,100],{"class":71},[33,1338,1339],{"class":103}," SearchResults",[33,1341,107],{"class":75},[33,1343,1088],{"class":110},[33,1345,293],{"class":75},[33,1347,1348],{"class":110},"results",[33,1350,293],{"class":75},[33,1352,1098],{"class":110},[33,1354,293],{"class":75},[33,1356,1357],{"class":110},"query",[33,1359,293],{"class":75},[33,1361,1362],{"class":110},"onRetry",[33,1364,114],{"class":75},[33,1366,1367],{"class":35,"line":301},[33,1368,1369],{"class":39},"  \u002F\u002F All hooks MUST come before any early return (Rules of Hooks — Ch 11)\n",[33,1371,1372,1374,1377,1380,1382,1385,1388,1390,1393,1395,1398],{"class":35,"line":308},[33,1373,900],{"class":71},[33,1375,1376],{"class":75}," [",[33,1378,1379],{"class":132},"retryCount",[33,1381,293],{"class":75},[33,1383,1384],{"class":132},"setRetryCount",[33,1386,1387],{"class":75},"] ",[33,1389,234],{"class":71},[33,1391,1392],{"class":103}," useState",[33,1394,915],{"class":75},[33,1396,1397],{"class":132},"0",[33,1399,933],{"class":75},[33,1401,1402],{"class":35,"line":318},[33,1403,65],{"emptyLinePlaceholder":64},[33,1405,1406,1409,1412,1414],{"class":35,"line":330},[33,1407,1408],{"class":103},"  useEffect",[33,1410,1411],{"class":75},"(() ",[33,1413,324],{"class":71},[33,1415,327],{"class":75},[33,1417,1418,1421,1423,1425,1427,1429,1431,1433,1435],{"class":35,"line":339},[33,1419,1420],{"class":71},"    if",[33,1422,1246],{"class":75},[33,1424,1110],{"class":71},[33,1426,1140],{"class":82},[33,1428,1253],{"class":75},[33,1430,1384],{"class":103},[33,1432,915],{"class":75},[33,1434,1397],{"class":132},[33,1436,933],{"class":75},[33,1438,1439],{"class":35,"line":367},[33,1440,1441],{"class":75},"  }, [status])\n",[33,1443,1444],{"class":35,"line":392},[33,1445,65],{"emptyLinePlaceholder":64},[33,1447,1448,1450,1452,1454,1457,1460,1462,1464,1467,1470,1472],{"class":35,"line":412},[33,1449,1243],{"class":71},[33,1451,1246],{"class":75},[33,1453,1110],{"class":71},[33,1455,1456],{"class":82}," 'idle'",[33,1458,1459],{"class":75},")    ",[33,1461,351],{"class":71},[33,1463,129],{"class":75},[33,1465,1466],{"class":132},"SearchPrompt",[33,1468,1469],{"class":103}," query",[33,1471,234],{"class":71},[33,1473,1474],{"class":75},"{query} \u002F>\n",[33,1476,1477,1479,1481,1483,1485,1487,1489,1491,1494,1497,1499,1502,1505],{"class":35,"line":430},[33,1478,1243],{"class":71},[33,1480,1246],{"class":75},[33,1482,1110],{"class":71},[33,1484,1113],{"class":82},[33,1486,1253],{"class":75},[33,1488,351],{"class":71},[33,1490,129],{"class":75},[33,1492,1493],{"class":132},"SkeletonLoader",[33,1495,1496],{"class":103}," count",[33,1498,234],{"class":71},[33,1500,1501],{"class":75},"{",[33,1503,1504],{"class":132},"5",[33,1506,1507],{"class":75},"} \u002F>\n",[33,1509,1510,1512,1514,1516,1518,1520,1522,1524,1527,1529,1531,1534,1536,1538,1541,1543,1546,1548,1550,1553,1555,1558,1561,1564,1567,1569,1572,1574,1576],{"class":35,"line":436},[33,1511,1243],{"class":71},[33,1513,1246],{"class":75},[33,1515,1110],{"class":71},[33,1517,1140],{"class":82},[33,1519,1274],{"class":75},[33,1521,351],{"class":71},[33,1523,129],{"class":75},[33,1525,1526],{"class":132},"ErrorState",[33,1528,1154],{"class":103},[33,1530,234],{"class":71},[33,1532,1533],{"class":75},"{error} ",[33,1535,1362],{"class":103},[33,1537,234],{"class":71},[33,1539,1540],{"class":75},"{() ",[33,1542,324],{"class":71},[33,1544,1545],{"class":75}," { ",[33,1547,1384],{"class":103},[33,1549,915],{"class":75},[33,1551,1552],{"class":110},"c",[33,1554,921],{"class":71},[33,1556,1557],{"class":75}," c ",[33,1559,1560],{"class":71},"+",[33,1562,1563],{"class":132}," 1",[33,1565,1566],{"class":75},"); ",[33,1568,1362],{"class":103},[33,1570,1571],{"class":75},"() }} ",[33,1573,1379],{"class":103},[33,1575,234],{"class":71},[33,1577,1578],{"class":75},"{retryCount} \u002F>\n",[33,1580,1581,1583,1585,1587,1589,1591,1594,1596,1598,1600],{"class":35,"line":442},[33,1582,1243],{"class":71},[33,1584,1246],{"class":75},[33,1586,1110],{"class":71},[33,1588,1172],{"class":82},[33,1590,526],{"class":71},[33,1592,1593],{"class":75}," results.",[33,1595,523],{"class":132},[33,1597,993],{"class":71},[33,1599,616],{"class":132},[33,1601,1602],{"class":75},") {\n",[33,1604,1605,1608,1610,1613,1616,1618,1620,1623,1625,1628],{"class":35,"line":451},[33,1606,1607],{"class":71},"    return",[33,1609,129],{"class":75},[33,1611,1612],{"class":132},"EmptyState",[33,1614,1615],{"class":103}," message",[33,1617,234],{"class":71},[33,1619,1501],{"class":75},[33,1621,1622],{"class":82},"`No results for \"${",[33,1624,1357],{"class":75},[33,1626,1627],{"class":82},"}\"`",[33,1629,1507],{"class":75},[33,1631,1632],{"class":35,"line":456},[33,1633,1634],{"class":75},"  }\n",[33,1636,1637,1639,1641,1643,1645],{"class":35,"line":462},[33,1638,1243],{"class":71},[33,1640,1246],{"class":75},[33,1642,1110],{"class":71},[33,1644,1172],{"class":82},[33,1646,1602],{"class":75},[33,1648,1649,1651],{"class":35,"line":468},[33,1650,1607],{"class":71},[33,1652,187],{"class":75},[33,1654,1655,1657,1659],{"class":35,"line":826},[33,1656,206],{"class":75},[33,1658,948],{"class":196},[33,1660,200],{"class":75},[33,1662,1663,1666,1668,1670,1673,1675],{"class":35,"line":847},[33,1664,1665],{"class":75},"        {results.",[33,1667,959],{"class":103},[33,1669,915],{"class":75},[33,1671,1672],{"class":110},"r",[33,1674,921],{"class":71},[33,1676,187],{"class":75},[33,1678,1679,1682,1684,1686,1688],{"class":35,"line":853},[33,1680,1681],{"class":75},"          \u003C",[33,1683,970],{"class":196},[33,1685,973],{"class":103},[33,1687,234],{"class":71},[33,1689,1690],{"class":75},"{r.id}>\n",[33,1692,1693,1696,1699,1702,1704],{"class":35,"line":862},[33,1694,1695],{"class":75},"            \u003C",[33,1697,1698],{"class":132},"ResultCard",[33,1700,1701],{"class":103}," data",[33,1703,234],{"class":71},[33,1705,1706],{"class":75},"{r} \u002F>\n",[33,1708,1709,1712,1714],{"class":35,"line":867},[33,1710,1711],{"class":75},"          \u003C\u002F",[33,1713,970],{"class":196},[33,1715,200],{"class":75},[33,1717,1718],{"class":35,"line":872},[33,1719,1720],{"class":75},"        ))}\n",[33,1722,1723,1726,1728],{"class":35,"line":877},[33,1724,1725],{"class":75},"      \u003C\u002F",[33,1727,948],{"class":196},[33,1729,200],{"class":75},[33,1731,1732],{"class":35,"line":883},[33,1733,1734],{"class":75},"    )\n",[33,1736,1737],{"class":35,"line":897},[33,1738,1634],{"class":75},[33,1740,1741,1743],{"class":35,"line":936},[33,1742,120],{"class":71},[33,1744,1199],{"class":132},[33,1746,1747],{"class":35,"line":943},[33,1748,153],{"class":75},[1750,1751,1753],"h3",{"id":1752},"rules-of-hooks-constraint-on-early-returns","Rules of Hooks Constraint on Early Returns",[19,1755,1757],{"filename":1756,"language":22},"hooks_before_returns.js",[24,1758,1760],{"className":26,"code":1759,"language":22,"meta":28,"style":28},"import { useState, useEffect } from 'react'\n\n\u002F\u002F BUG: useState called AFTER an early return — hook count varies between renders\nfunction DiscountBannerBad({ cartTotal }) {\n  if (cartTotal \u003C 50) return null              \u002F\u002F ← early return\n  const [dismissed, setDismissed] = useState(false)  \u002F\u002F ← hook AFTER return\n  if (dismissed) return null\n  return (\n    \u003Cdiv className=\"banner\">\n      Free shipping! \u003Cbutton onClick={() => setDismissed(true)}>Dismiss\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  )\n  \u002F\u002F When cartTotal \u003C 50: 0 hooks called. When cartTotal >= 50: 1 hook called.\n  \u002F\u002F React throws: \"Rendered fewer hooks than expected. This may be caused by an\n  \u002F\u002F accidental early return statement.\" Hook state corrupts silently before the error.\n}\n\n\u002F\u002F FIX: all hooks unconditionally before any return\nfunction DiscountBannerGood({ cartTotal }) {\n  const [dismissed, setDismissed] = useState(false)\n\n  if (cartTotal \u003C 50) return null\n  if (dismissed)      return null\n\n  return (\n    \u003Cdiv className=\"banner\">\n      Free shipping! \u003Cbutton onClick={() => setDismissed(true)}>Dismiss\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  )\n  \u002F\u002F Hook count is constant (1) on every render regardless of branch taken.\n}\n",[30,1761,1762,1772,1776,1781,1795,1817,1848,1859,1865,1880,1912,1920,1924,1929,1934,1939,1943,1947,1952,1965,1989,1993,2009,2020,2024,2030,2044,2070,2078,2082,2087],{"__ignoreMap":28},[33,1763,1764,1766,1768,1770],{"class":35,"line":36},[33,1765,72],{"class":71},[33,1767,1063],{"class":75},[33,1769,79],{"class":71},[33,1771,83],{"class":82},[33,1773,1774],{"class":35,"line":43},[33,1775,65],{"emptyLinePlaceholder":64},[33,1777,1778],{"class":35,"line":49},[33,1779,1780],{"class":39},"\u002F\u002F BUG: useState called AFTER an early return — hook count varies between renders\n",[33,1782,1783,1785,1788,1790,1793],{"class":35,"line":55},[33,1784,100],{"class":71},[33,1786,1787],{"class":103}," DiscountBannerBad",[33,1789,107],{"class":75},[33,1791,1792],{"class":110},"cartTotal",[33,1794,114],{"class":75},[33,1796,1797,1799,1802,1805,1808,1810,1812,1814],{"class":35,"line":61},[33,1798,1243],{"class":71},[33,1800,1801],{"class":75}," (cartTotal ",[33,1803,1804],{"class":71},"\u003C",[33,1806,1807],{"class":132}," 50",[33,1809,1253],{"class":75},[33,1811,351],{"class":71},[33,1813,731],{"class":132},[33,1815,1816],{"class":39},"              \u002F\u002F ← early return\n",[33,1818,1819,1821,1823,1826,1828,1831,1833,1835,1837,1839,1842,1845],{"class":35,"line":68},[33,1820,900],{"class":71},[33,1822,1376],{"class":75},[33,1824,1825],{"class":132},"dismissed",[33,1827,293],{"class":75},[33,1829,1830],{"class":132},"setDismissed",[33,1832,1387],{"class":75},[33,1834,234],{"class":71},[33,1836,1392],{"class":103},[33,1838,915],{"class":75},[33,1840,1841],{"class":132},"false",[33,1843,1844],{"class":75},")  ",[33,1846,1847],{"class":39},"\u002F\u002F ← hook AFTER return\n",[33,1849,1850,1852,1855,1857],{"class":35,"line":86},[33,1851,1243],{"class":71},[33,1853,1854],{"class":75}," (dismissed) ",[33,1856,351],{"class":71},[33,1858,1199],{"class":132},[33,1860,1861,1863],{"class":35,"line":91},[33,1862,120],{"class":71},[33,1864,187],{"class":75},[33,1866,1867,1869,1871,1873,1875,1878],{"class":35,"line":97},[33,1868,193],{"class":75},[33,1870,197],{"class":196},[33,1872,231],{"class":103},[33,1874,234],{"class":71},[33,1876,1877],{"class":82},"\"banner\"",[33,1879,200],{"class":75},[33,1881,1882,1885,1888,1891,1893,1895,1897,1900,1902,1905,1908,1910],{"class":35,"line":117},[33,1883,1884],{"class":75},"      Free shipping! \u003C",[33,1886,1887],{"class":196},"button",[33,1889,1890],{"class":103}," onClick",[33,1892,234],{"class":71},[33,1894,1540],{"class":75},[33,1896,324],{"class":71},[33,1898,1899],{"class":103}," setDismissed",[33,1901,915],{"class":75},[33,1903,1904],{"class":132},"true",[33,1906,1907],{"class":75},")}>Dismiss\u003C\u002F",[33,1909,1887],{"class":196},[33,1911,200],{"class":75},[33,1913,1914,1916,1918],{"class":35,"line":150},[33,1915,251],{"class":75},[33,1917,197],{"class":196},[33,1919,200],{"class":75},[33,1921,1922],{"class":35,"line":156},[33,1923,261],{"class":75},[33,1925,1926],{"class":35,"line":161},[33,1927,1928],{"class":39},"  \u002F\u002F When cartTotal \u003C 50: 0 hooks called. When cartTotal >= 50: 1 hook called.\n",[33,1930,1931],{"class":35,"line":167},[33,1932,1933],{"class":39},"  \u002F\u002F React throws: \"Rendered fewer hooks than expected. This may be caused by an\n",[33,1935,1936],{"class":35,"line":182},[33,1937,1938],{"class":39},"  \u002F\u002F accidental early return statement.\" Hook state corrupts silently before the error.\n",[33,1940,1941],{"class":35,"line":190},[33,1942,153],{"class":75},[33,1944,1945],{"class":35,"line":203},[33,1946,65],{"emptyLinePlaceholder":64},[33,1948,1949],{"class":35,"line":218},[33,1950,1951],{"class":39},"\u002F\u002F FIX: all hooks unconditionally before any return\n",[33,1953,1954,1956,1959,1961,1963],{"class":35,"line":248},[33,1955,100],{"class":71},[33,1957,1958],{"class":103}," DiscountBannerGood",[33,1960,107],{"class":75},[33,1962,1792],{"class":110},[33,1964,114],{"class":75},[33,1966,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987],{"class":35,"line":258},[33,1968,900],{"class":71},[33,1970,1376],{"class":75},[33,1972,1825],{"class":132},[33,1974,293],{"class":75},[33,1976,1830],{"class":132},[33,1978,1387],{"class":75},[33,1980,234],{"class":71},[33,1982,1392],{"class":103},[33,1984,915],{"class":75},[33,1986,1841],{"class":132},[33,1988,933],{"class":75},[33,1990,1991],{"class":35,"line":264},[33,1992,65],{"emptyLinePlaceholder":64},[33,1994,1995,1997,1999,2001,2003,2005,2007],{"class":35,"line":269},[33,1996,1243],{"class":71},[33,1998,1801],{"class":75},[33,2000,1804],{"class":71},[33,2002,1807],{"class":132},[33,2004,1253],{"class":75},[33,2006,351],{"class":71},[33,2008,1199],{"class":132},[33,2010,2011,2013,2016,2018],{"class":35,"line":274},[33,2012,1243],{"class":71},[33,2014,2015],{"class":75}," (dismissed)      ",[33,2017,351],{"class":71},[33,2019,1199],{"class":132},[33,2021,2022],{"class":35,"line":280},[33,2023,65],{"emptyLinePlaceholder":64},[33,2025,2026,2028],{"class":35,"line":301},[33,2027,120],{"class":71},[33,2029,187],{"class":75},[33,2031,2032,2034,2036,2038,2040,2042],{"class":35,"line":308},[33,2033,193],{"class":75},[33,2035,197],{"class":196},[33,2037,231],{"class":103},[33,2039,234],{"class":71},[33,2041,1877],{"class":82},[33,2043,200],{"class":75},[33,2045,2046,2048,2050,2052,2054,2056,2058,2060,2062,2064,2066,2068],{"class":35,"line":318},[33,2047,1884],{"class":75},[33,2049,1887],{"class":196},[33,2051,1890],{"class":103},[33,2053,234],{"class":71},[33,2055,1540],{"class":75},[33,2057,324],{"class":71},[33,2059,1899],{"class":103},[33,2061,915],{"class":75},[33,2063,1904],{"class":132},[33,2065,1907],{"class":75},[33,2067,1887],{"class":196},[33,2069,200],{"class":75},[33,2071,2072,2074,2076],{"class":35,"line":330},[33,2073,251],{"class":75},[33,2075,197],{"class":196},[33,2077,200],{"class":75},[33,2079,2080],{"class":35,"line":339},[33,2081,261],{"class":75},[33,2083,2084],{"class":35,"line":367},[33,2085,2086],{"class":39},"  \u002F\u002F Hook count is constant (1) on every render regardless of branch taken.\n",[33,2088,2089],{"class":35,"line":392},[33,2090,153],{"class":75},[14,2092,2094],{"id":2093},"enum-objects-for-multi-state-rendering","Enum Objects for Multi-State Rendering",[19,2096,2098],{"filename":2097,"language":22},"enum_lookups.js",[24,2099,2101],{"className":26,"code":2100,"language":22,"meta":28,"style":28},"import { useState } from 'react'\n\n\u002F\u002F ANTI-PATTERN: long if\u002Felse-if chain or nested ternaries for N branches\nfunction StatusBadgeBad({ status }) {\n  if (status === 'pending')   return \u003CBadge color=\"yellow\">Pending\u003C\u002FBadge>\n  if (status === 'approved')  return \u003CBadge color=\"green\">Approved\u003C\u002FBadge>\n  if (status === 'rejected')  return \u003CBadge color=\"red\">Rejected\u003C\u002FBadge>\n  if (status === 'cancelled') return \u003CBadge color=\"gray\">Cancelled\u003C\u002FBadge>\n  if (status === 'expired')   return \u003CBadge color=\"orange\">Expired\u003C\u002FBadge>\n  return \u003CBadge color=\"blue\">Unknown\u003C\u002FBadge>\n  \u002F\u002F Linear scan, hard to extend, easy to forget a case.\n}\n\n\u002F\u002F CORRECT: enum object — flat data-driven lookup, O(1), trivially extensible\nconst STATUS_CONFIG = {\n  pending:   { label: 'Pending',   color: 'yellow',  icon: ClockIcon },\n  approved:  { label: 'Approved',  color: 'green',   icon: CheckIcon },\n  rejected:  { label: 'Rejected',  color: 'red',     icon: XIcon },\n  cancelled: { label: 'Cancelled', color: 'gray',    icon: BanIcon },\n  expired:   { label: 'Expired',   color: 'orange',  icon: WarningIcon },\n}\n\nfunction StatusBadge({ status }) {\n  const config = STATUS_CONFIG[status] ?? { label: 'Unknown', color: 'blue', icon: QuestionIcon }\n  const Icon = config.icon\n  return (\n    \u003CBadge color={config.color}>\n      \u003CIcon \u002F> {config.label}\n    \u003C\u002FBadge>\n  )\n  \u002F\u002F The ?? fallback handles any status value not in the map — no silent undefined render.\n}\n\n\u002F\u002F COMPLEX: component registry — map status → component class, render dynamically\nconst STEP_COMPONENTS = {\n  account:      AccountStep,\n  billing:      BillingStep,\n  shipping:     ShippingStep,\n  confirmation: ConfirmationStep,\n}\n\nfunction CheckoutWizard({ currentStep, ...stepProps }) {\n  const StepComponent = STEP_COMPONENTS[currentStep]\n  if (!StepComponent) {\n    throw new Error(`Unknown checkout step: \"${currentStep}\". Valid: ${Object.keys(STEP_COMPONENTS).join(', ')}`)\n    \u002F\u002F Throw early with a diagnostic message — a typo'd step name surfaces immediately\n    \u002F\u002F instead of rendering undefined (which throws the cryptic \"Element type is invalid\").\n  }\n  return \u003CStepComponent {...stepProps} \u002F>\n}\n\n\u002F\u002F COMPLEX: enum with render functions (not just static config)\nconst NOTIFICATION_RENDERERS = {\n  info:    (msg) => \u003CInfoAlert message={msg} \u002F>,\n  success: (msg) => \u003CSuccessAlert message={msg} \u002F>,\n  warning: (msg) => \u003CWarningAlert message={msg} \u002F>,\n  error:   (msg) => \u003CErrorAlert message={msg} \u002F>,\n}\n\nfunction Notification({ type, message }) {\n  const render = NOTIFICATION_RENDERERS[type] ?? NOTIFICATION_RENDERERS.info\n  return render(message)\n}\n",[30,2102,2103,2114,2118,2123,2136,2171,2204,2237,2270,2303,2325,2330,2334,2338,2343,2355,2372,2389,2405,2422,2438,2442,2446,2459,2490,2502,2508,2521,2531,2539,2543,2548,2552,2556,2561,2572,2577,2582,2587,2592,2596,2600,2622,2636,2649,2703,2708,2713,2717,2734,2738,2742,2747,2758,2785,2810,2834,2859,2864,2869,2888,2910,2920],{"__ignoreMap":28},[33,2104,2105,2107,2110,2112],{"class":35,"line":36},[33,2106,72],{"class":71},[33,2108,2109],{"class":75}," { useState } ",[33,2111,79],{"class":71},[33,2113,83],{"class":82},[33,2115,2116],{"class":35,"line":43},[33,2117,65],{"emptyLinePlaceholder":64},[33,2119,2120],{"class":35,"line":49},[33,2121,2122],{"class":39},"\u002F\u002F ANTI-PATTERN: long if\u002Felse-if chain or nested ternaries for N branches\n",[33,2124,2125,2127,2130,2132,2134],{"class":35,"line":55},[33,2126,100],{"class":71},[33,2128,2129],{"class":103}," StatusBadgeBad",[33,2131,107],{"class":75},[33,2133,1088],{"class":110},[33,2135,114],{"class":75},[33,2137,2138,2140,2142,2144,2147,2149,2151,2153,2156,2159,2161,2164,2167,2169],{"class":35,"line":61},[33,2139,1243],{"class":71},[33,2141,1246],{"class":75},[33,2143,1110],{"class":71},[33,2145,2146],{"class":82}," 'pending'",[33,2148,1274],{"class":75},[33,2150,351],{"class":71},[33,2152,129],{"class":75},[33,2154,2155],{"class":132},"Badge",[33,2157,2158],{"class":103}," color",[33,2160,234],{"class":71},[33,2162,2163],{"class":82},"\"yellow\"",[33,2165,2166],{"class":75},">Pending\u003C\u002F",[33,2168,2155],{"class":132},[33,2170,200],{"class":75},[33,2172,2173,2175,2177,2179,2182,2184,2186,2188,2190,2192,2194,2197,2200,2202],{"class":35,"line":68},[33,2174,1243],{"class":71},[33,2176,1246],{"class":75},[33,2178,1110],{"class":71},[33,2180,2181],{"class":82}," 'approved'",[33,2183,1844],{"class":75},[33,2185,351],{"class":71},[33,2187,129],{"class":75},[33,2189,2155],{"class":132},[33,2191,2158],{"class":103},[33,2193,234],{"class":71},[33,2195,2196],{"class":82},"\"green\"",[33,2198,2199],{"class":75},">Approved\u003C\u002F",[33,2201,2155],{"class":132},[33,2203,200],{"class":75},[33,2205,2206,2208,2210,2212,2215,2217,2219,2221,2223,2225,2227,2230,2233,2235],{"class":35,"line":86},[33,2207,1243],{"class":71},[33,2209,1246],{"class":75},[33,2211,1110],{"class":71},[33,2213,2214],{"class":82}," 'rejected'",[33,2216,1844],{"class":75},[33,2218,351],{"class":71},[33,2220,129],{"class":75},[33,2222,2155],{"class":132},[33,2224,2158],{"class":103},[33,2226,234],{"class":71},[33,2228,2229],{"class":82},"\"red\"",[33,2231,2232],{"class":75},">Rejected\u003C\u002F",[33,2234,2155],{"class":132},[33,2236,200],{"class":75},[33,2238,2239,2241,2243,2245,2248,2250,2252,2254,2256,2258,2260,2263,2266,2268],{"class":35,"line":91},[33,2240,1243],{"class":71},[33,2242,1246],{"class":75},[33,2244,1110],{"class":71},[33,2246,2247],{"class":82}," 'cancelled'",[33,2249,1253],{"class":75},[33,2251,351],{"class":71},[33,2253,129],{"class":75},[33,2255,2155],{"class":132},[33,2257,2158],{"class":103},[33,2259,234],{"class":71},[33,2261,2262],{"class":82},"\"gray\"",[33,2264,2265],{"class":75},">Cancelled\u003C\u002F",[33,2267,2155],{"class":132},[33,2269,200],{"class":75},[33,2271,2272,2274,2276,2278,2281,2283,2285,2287,2289,2291,2293,2296,2299,2301],{"class":35,"line":97},[33,2273,1243],{"class":71},[33,2275,1246],{"class":75},[33,2277,1110],{"class":71},[33,2279,2280],{"class":82}," 'expired'",[33,2282,1274],{"class":75},[33,2284,351],{"class":71},[33,2286,129],{"class":75},[33,2288,2155],{"class":132},[33,2290,2158],{"class":103},[33,2292,234],{"class":71},[33,2294,2295],{"class":82},"\"orange\"",[33,2297,2298],{"class":75},">Expired\u003C\u002F",[33,2300,2155],{"class":132},[33,2302,200],{"class":75},[33,2304,2305,2307,2309,2311,2313,2315,2318,2321,2323],{"class":35,"line":117},[33,2306,120],{"class":71},[33,2308,129],{"class":75},[33,2310,2155],{"class":132},[33,2312,2158],{"class":103},[33,2314,234],{"class":71},[33,2316,2317],{"class":82},"\"blue\"",[33,2319,2320],{"class":75},">Unknown\u003C\u002F",[33,2322,2155],{"class":132},[33,2324,200],{"class":75},[33,2326,2327],{"class":35,"line":150},[33,2328,2329],{"class":39},"  \u002F\u002F Linear scan, hard to extend, easy to forget a case.\n",[33,2331,2332],{"class":35,"line":156},[33,2333,153],{"class":75},[33,2335,2336],{"class":35,"line":161},[33,2337,65],{"emptyLinePlaceholder":64},[33,2339,2340],{"class":35,"line":167},[33,2341,2342],{"class":39},"\u002F\u002F CORRECT: enum object — flat data-driven lookup, O(1), trivially extensible\n",[33,2344,2345,2348,2351,2353],{"class":35,"line":182},[33,2346,2347],{"class":71},"const",[33,2349,2350],{"class":132}," STATUS_CONFIG",[33,2352,906],{"class":71},[33,2354,327],{"class":75},[33,2356,2357,2360,2363,2366,2369],{"class":35,"line":190},[33,2358,2359],{"class":75},"  pending:   { label: ",[33,2361,2362],{"class":82},"'Pending'",[33,2364,2365],{"class":75},",   color: ",[33,2367,2368],{"class":82},"'yellow'",[33,2370,2371],{"class":75},",  icon: ClockIcon },\n",[33,2373,2374,2377,2380,2383,2386],{"class":35,"line":203},[33,2375,2376],{"class":75},"  approved:  { label: ",[33,2378,2379],{"class":82},"'Approved'",[33,2381,2382],{"class":75},",  color: ",[33,2384,2385],{"class":82},"'green'",[33,2387,2388],{"class":75},",   icon: CheckIcon },\n",[33,2390,2391,2394,2397,2399,2402],{"class":35,"line":218},[33,2392,2393],{"class":75},"  rejected:  { label: ",[33,2395,2396],{"class":82},"'Rejected'",[33,2398,2382],{"class":75},[33,2400,2401],{"class":82},"'red'",[33,2403,2404],{"class":75},",     icon: XIcon },\n",[33,2406,2407,2410,2413,2416,2419],{"class":35,"line":248},[33,2408,2409],{"class":75},"  cancelled: { label: ",[33,2411,2412],{"class":82},"'Cancelled'",[33,2414,2415],{"class":75},", color: ",[33,2417,2418],{"class":82},"'gray'",[33,2420,2421],{"class":75},",    icon: BanIcon },\n",[33,2423,2424,2427,2430,2432,2435],{"class":35,"line":258},[33,2425,2426],{"class":75},"  expired:   { label: ",[33,2428,2429],{"class":82},"'Expired'",[33,2431,2365],{"class":75},[33,2433,2434],{"class":82},"'orange'",[33,2436,2437],{"class":75},",  icon: WarningIcon },\n",[33,2439,2440],{"class":35,"line":264},[33,2441,153],{"class":75},[33,2443,2444],{"class":35,"line":269},[33,2445,65],{"emptyLinePlaceholder":64},[33,2447,2448,2450,2453,2455,2457],{"class":35,"line":274},[33,2449,100],{"class":71},[33,2451,2452],{"class":103}," StatusBadge",[33,2454,107],{"class":75},[33,2456,1088],{"class":110},[33,2458,114],{"class":75},[33,2460,2461,2463,2466,2468,2470,2473,2476,2479,2482,2484,2487],{"class":35,"line":280},[33,2462,900],{"class":71},[33,2464,2465],{"class":132}," config",[33,2467,906],{"class":71},[33,2469,2350],{"class":132},[33,2471,2472],{"class":75},"[status] ",[33,2474,2475],{"class":71},"??",[33,2477,2478],{"class":75}," { label: ",[33,2480,2481],{"class":82},"'Unknown'",[33,2483,2415],{"class":75},[33,2485,2486],{"class":82},"'blue'",[33,2488,2489],{"class":75},", icon: QuestionIcon }\n",[33,2491,2492,2494,2497,2499],{"class":35,"line":301},[33,2493,900],{"class":71},[33,2495,2496],{"class":132}," Icon",[33,2498,906],{"class":71},[33,2500,2501],{"class":75}," config.icon\n",[33,2503,2504,2506],{"class":35,"line":308},[33,2505,120],{"class":71},[33,2507,187],{"class":75},[33,2509,2510,2512,2514,2516,2518],{"class":35,"line":318},[33,2511,193],{"class":75},[33,2513,2155],{"class":132},[33,2515,2158],{"class":103},[33,2517,234],{"class":71},[33,2519,2520],{"class":75},"{config.color}>\n",[33,2522,2523,2525,2528],{"class":35,"line":330},[33,2524,206],{"class":75},[33,2526,2527],{"class":132},"Icon",[33,2529,2530],{"class":75}," \u002F> {config.label}\n",[33,2532,2533,2535,2537],{"class":35,"line":339},[33,2534,251],{"class":75},[33,2536,2155],{"class":132},[33,2538,200],{"class":75},[33,2540,2541],{"class":35,"line":367},[33,2542,261],{"class":75},[33,2544,2545],{"class":35,"line":392},[33,2546,2547],{"class":39},"  \u002F\u002F The ?? fallback handles any status value not in the map — no silent undefined render.\n",[33,2549,2550],{"class":35,"line":412},[33,2551,153],{"class":75},[33,2553,2554],{"class":35,"line":430},[33,2555,65],{"emptyLinePlaceholder":64},[33,2557,2558],{"class":35,"line":436},[33,2559,2560],{"class":39},"\u002F\u002F COMPLEX: component registry — map status → component class, render dynamically\n",[33,2562,2563,2565,2568,2570],{"class":35,"line":442},[33,2564,2347],{"class":71},[33,2566,2567],{"class":132}," STEP_COMPONENTS",[33,2569,906],{"class":71},[33,2571,327],{"class":75},[33,2573,2574],{"class":35,"line":451},[33,2575,2576],{"class":75},"  account:      AccountStep,\n",[33,2578,2579],{"class":35,"line":456},[33,2580,2581],{"class":75},"  billing:      BillingStep,\n",[33,2583,2584],{"class":35,"line":462},[33,2585,2586],{"class":75},"  shipping:     ShippingStep,\n",[33,2588,2589],{"class":35,"line":468},[33,2590,2591],{"class":75},"  confirmation: ConfirmationStep,\n",[33,2593,2594],{"class":35,"line":826},[33,2595,153],{"class":75},[33,2597,2598],{"class":35,"line":847},[33,2599,65],{"emptyLinePlaceholder":64},[33,2601,2602,2604,2607,2609,2612,2614,2617,2620],{"class":35,"line":853},[33,2603,100],{"class":71},[33,2605,2606],{"class":103}," CheckoutWizard",[33,2608,107],{"class":75},[33,2610,2611],{"class":110},"currentStep",[33,2613,293],{"class":75},[33,2615,2616],{"class":71},"...",[33,2618,2619],{"class":110},"stepProps",[33,2621,114],{"class":75},[33,2623,2624,2626,2629,2631,2633],{"class":35,"line":862},[33,2625,900],{"class":71},[33,2627,2628],{"class":132}," StepComponent",[33,2630,906],{"class":71},[33,2632,2567],{"class":132},[33,2634,2635],{"class":75},"[currentStep]\n",[33,2637,2638,2640,2643,2646],{"class":35,"line":867},[33,2639,1243],{"class":71},[33,2641,2642],{"class":75}," (",[33,2644,2645],{"class":71},"!",[33,2647,2648],{"class":75},"StepComponent) {\n",[33,2650,2651,2654,2657,2660,2662,2665,2667,2670,2673,2676,2679,2681,2684,2687,2690,2692,2695,2698,2701],{"class":35,"line":872},[33,2652,2653],{"class":71},"    throw",[33,2655,2656],{"class":71}," new",[33,2658,2659],{"class":103}," Error",[33,2661,915],{"class":75},[33,2663,2664],{"class":82},"`Unknown checkout step: \"${",[33,2666,2611],{"class":75},[33,2668,2669],{"class":82},"}\". Valid: ${",[33,2671,2672],{"class":75},"Object",[33,2674,2675],{"class":82},".",[33,2677,2678],{"class":103},"keys",[33,2680,915],{"class":82},[33,2682,2683],{"class":132},"STEP_COMPONENTS",[33,2685,2686],{"class":82},").",[33,2688,2689],{"class":103},"join",[33,2691,915],{"class":82},[33,2693,2694],{"class":82},"', '",[33,2696,2697],{"class":82},")",[33,2699,2700],{"class":82},"}`",[33,2702,933],{"class":75},[33,2704,2705],{"class":35,"line":877},[33,2706,2707],{"class":39},"    \u002F\u002F Throw early with a diagnostic message — a typo'd step name surfaces immediately\n",[33,2709,2710],{"class":35,"line":883},[33,2711,2712],{"class":39},"    \u002F\u002F instead of rendering undefined (which throws the cryptic \"Element type is invalid\").\n",[33,2714,2715],{"class":35,"line":897},[33,2716,1634],{"class":75},[33,2718,2719,2721,2723,2726,2729,2731],{"class":35,"line":936},[33,2720,120],{"class":71},[33,2722,129],{"class":75},[33,2724,2725],{"class":132},"StepComponent",[33,2727,2728],{"class":75}," {",[33,2730,2616],{"class":71},[33,2732,2733],{"class":75},"stepProps} \u002F>\n",[33,2735,2736],{"class":35,"line":943},[33,2737,153],{"class":75},[33,2739,2740],{"class":35,"line":953},[33,2741,65],{"emptyLinePlaceholder":64},[33,2743,2744],{"class":35,"line":986},[33,2745,2746],{"class":39},"\u002F\u002F COMPLEX: enum with render functions (not just static config)\n",[33,2748,2749,2751,2754,2756],{"class":35,"line":1011},[33,2750,2347],{"class":71},[33,2752,2753],{"class":132}," NOTIFICATION_RENDERERS",[33,2755,906],{"class":71},[33,2757,327],{"class":75},[33,2759,2760,2763,2766,2769,2771,2773,2775,2778,2780,2782],{"class":35,"line":1022},[33,2761,2762],{"class":103},"  info",[33,2764,2765],{"class":75},":    (",[33,2767,2768],{"class":110},"msg",[33,2770,1253],{"class":75},[33,2772,324],{"class":71},[33,2774,129],{"class":75},[33,2776,2777],{"class":132},"InfoAlert",[33,2779,1615],{"class":103},[33,2781,234],{"class":71},[33,2783,2784],{"class":75},"{msg} \u002F>,\n",[33,2786,2787,2790,2793,2795,2797,2799,2801,2804,2806,2808],{"class":35,"line":1028},[33,2788,2789],{"class":103},"  success",[33,2791,2792],{"class":75},": (",[33,2794,2768],{"class":110},[33,2796,1253],{"class":75},[33,2798,324],{"class":71},[33,2800,129],{"class":75},[33,2802,2803],{"class":132},"SuccessAlert",[33,2805,1615],{"class":103},[33,2807,234],{"class":71},[33,2809,2784],{"class":75},[33,2811,2812,2815,2817,2819,2821,2823,2825,2828,2830,2832],{"class":35,"line":1037},[33,2813,2814],{"class":103},"  warning",[33,2816,2792],{"class":75},[33,2818,2768],{"class":110},[33,2820,1253],{"class":75},[33,2822,324],{"class":71},[33,2824,129],{"class":75},[33,2826,2827],{"class":132},"WarningAlert",[33,2829,1615],{"class":103},[33,2831,234],{"class":71},[33,2833,2784],{"class":75},[33,2835,2836,2839,2842,2844,2846,2848,2850,2853,2855,2857],{"class":35,"line":1042},[33,2837,2838],{"class":103},"  error",[33,2840,2841],{"class":75},":   (",[33,2843,2768],{"class":110},[33,2845,1253],{"class":75},[33,2847,324],{"class":71},[33,2849,129],{"class":75},[33,2851,2852],{"class":132},"ErrorAlert",[33,2854,1615],{"class":103},[33,2856,234],{"class":71},[33,2858,2784],{"class":75},[33,2860,2862],{"class":35,"line":2861},58,[33,2863,153],{"class":75},[33,2865,2867],{"class":35,"line":2866},59,[33,2868,65],{"emptyLinePlaceholder":64},[33,2870,2872,2874,2877,2879,2881,2883,2886],{"class":35,"line":2871},60,[33,2873,100],{"class":71},[33,2875,2876],{"class":103}," Notification",[33,2878,107],{"class":75},[33,2880,290],{"class":110},[33,2882,293],{"class":75},[33,2884,2885],{"class":110},"message",[33,2887,114],{"class":75},[33,2889,2891,2893,2896,2898,2900,2903,2905,2907],{"class":35,"line":2890},61,[33,2892,900],{"class":71},[33,2894,2895],{"class":132}," render",[33,2897,906],{"class":71},[33,2899,2753],{"class":132},[33,2901,2902],{"class":75},"[type] ",[33,2904,2475],{"class":71},[33,2906,2753],{"class":132},[33,2908,2909],{"class":75},".info\n",[33,2911,2913,2915,2917],{"class":35,"line":2912},62,[33,2914,120],{"class":71},[33,2916,2895],{"class":103},[33,2918,2919],{"class":75},"(message)\n",[33,2921,2923],{"class":35,"line":2922},63,[33,2924,153],{"class":75},[14,2926,2928],{"id":2927},"showhide-vs-mountunmount","Show\u002FHide vs Mount\u002FUnmount",[19,2930,2932],{"filename":2931,"language":22},"show_hide_vs_mount.js",[24,2933,2935],{"className":26,"code":2934,"language":22,"meta":28,"style":28},"import { useState, useRef, useEffect } from 'react'\n\n\u002F\u002F ── MOUNT\u002FUNMOUNT: conditionally render (component is created\u002Fdestroyed) ──\nfunction TabPanelMount({ activeTab, tabs }) {\n  return (\n    \u003Cdiv>\n      {tabs.map(tab => (\n        \u003Cbutton key={tab.id} onClick={() => tabs.onChange(tab.id)}>\n          {tab.label}\n        \u003C\u002Fbutton>\n      ))}\n      {activeTab === 'overview' && \u003COverviewPanel \u002F>}\n      {activeTab === 'details'  && \u003CDetailsPanel \u002F>}\n      {activeTab === 'reviews'  && \u003CReviewsPanel \u002F>}\n      {\u002F* Only the active panel exists in the DOM at any time.\n          Switching tabs unmounts the old panel (state lost, effects cleaned up)\n          and mounts the new one (fresh state, effects re-run). *\u002F}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ── SHOW\u002FHIDE: keep mounted, toggle visibility via CSS ──\nfunction TabPanelShowHide({ activeTab, tabs }) {\n  return (\n    \u003Cdiv>\n      {tabs.map(tab => (\n        \u003Cbutton key={tab.id} onClick={() => tabs.onChange(tab.id)}>\n          {tab.label}\n        \u003C\u002Fbutton>\n      ))}\n      \u003Cdiv style={{ display: activeTab === 'overview' ? 'block' : 'none' }}>\n        \u003COverviewPanel \u002F>\n      \u003C\u002Fdiv>\n      \u003Cdiv style={{ display: activeTab === 'details' ? 'block' : 'none' }}>\n        \u003CDetailsPanel \u002F>\n      \u003C\u002Fdiv>\n      \u003Cdiv style={{ display: activeTab === 'reviews' ? 'block' : 'none' }}>\n        \u003CReviewsPanel \u002F>\n      \u003C\u002Fdiv>\n      {\u002F* All panels remain mounted — state persists across tab switches.\n          But: all panels' effects run simultaneously, all are in the DOM (heavier). *\u002F}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ── WHEN TO USE WHICH ──\n\u002F\u002F MOUNT\u002FUNMOUNT (conditional render):\n\u002F\u002F   ✓ Lightweight panels, no expensive state to preserve\n\u002F\u002F   ✓ Panels with heavy initial data fetching (only fetch the visible one)\n\u002F\u002F   ✓ Forms that should reset on tab switch\n\u002F\u002F   ✗ Bad when: user loses in-progress form data on tab switch\n\n\u002F\u002F SHOW\u002FHIDE (CSS display):\n\u002F\u002F   ✓ Preserve component state (scroll position, form input, expanded accordions)\n\u002F\u002F   ✓ Avoid re-running expensive effects (data fetching, subscriptions)\n\u002F\u002F   ✓ Heavy components where mount cost is high (charts, editors, maps)\n\u002F\u002F   ✗ Bad when: many panels — all are in DOM simultaneously, bloating memory\n\u002F\u002F   ✗ Bad when: effects should not run when panel is not visible (analytics, polling)\n\n\u002F\u002F COMPLEX: hybrid — keep recently-visited panels mounted, unmount distant ones\nfunction SmartTabPanels({ activeTab, tabIds }) {\n  const [mountedTabs, setMountedTabs] = useState(new Set([activeTab]))\n\n  useEffect(() => {\n    setMountedTabs(prev => new Set([...prev, activeTab]))\n    \u002F\u002F Once a tab has been visited, keep it mounted (preserve state).\n    \u002F\u002F Only the active tab is visible; previously-visited tabs are display:none.\n  }, [activeTab])\n\n  return (\n    \u003Cdiv>\n      {tabIds.map(tabId => {\n        if (!mountedTabs.has(tabId)) return null  \u002F\u002F never-visited: don't mount\n        const isVisible = tabId === activeTab\n        return (\n          \u003Cdiv key={tabId} style={{ display: isVisible ? 'block' : 'none' }}>\n            \u003CTabContent tabId={tabId} \u002F>\n          \u003C\u002Fdiv>\n        )\n      })}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ANTI-PATTERN: unmounting to \"reset\" a form when the user just switched tabs\nfunction BadSettingsPage({ activeSection }) {\n  return (\n    \u003Cdiv>\n      {activeSection === 'profile'   && \u003CProfileForm \u002F>}\n      {activeSection === 'security'  && \u003CSecurityForm \u002F>}\n      {activeSection === 'notifications' && \u003CNotificationForm \u002F>}\n      {\u002F* User fills half the ProfileForm, clicks Security to check something,\n          clicks back to Profile → form is BLANK (unmounted + remounted = state lost).\n          Use show\u002Fhide or persist form state to parent\u002FContext instead. *\u002F}\n    \u003C\u002Fdiv>\n  )\n}\n",[30,2936,2937,2948,2952,2957,2976,2982,2990,3006,3037,3042,3051,3056,3076,3095,3113,3121,3126,3133,3141,3145,3149,3153,3158,3175,3181,3189,3203,3229,3233,3241,3245,3277,3285,3293,3319,3327,3335,3361,3369,3377,3384,3391,3399,3403,3407,3411,3416,3421,3426,3431,3436,3441,3445,3450,3455,3460,3465,3470,3475,3479,3484,3502,3533,3537,3548,3573,3579,3585,3591,3596,3603,3612,3629,3655,3674,3682,3714,3730,3739,3745,3751,3760,3765,3770,3775,3781,3796,3803,3812,3833,3852,3871,3879,3885,3893,3902,3907],{"__ignoreMap":28},[33,2938,2939,2941,2944,2946],{"class":35,"line":36},[33,2940,72],{"class":71},[33,2942,2943],{"class":75}," { useState, useRef, useEffect } ",[33,2945,79],{"class":71},[33,2947,83],{"class":82},[33,2949,2950],{"class":35,"line":43},[33,2951,65],{"emptyLinePlaceholder":64},[33,2953,2954],{"class":35,"line":49},[33,2955,2956],{"class":39},"\u002F\u002F ── MOUNT\u002FUNMOUNT: conditionally render (component is created\u002Fdestroyed) ──\n",[33,2958,2959,2961,2964,2966,2969,2971,2974],{"class":35,"line":55},[33,2960,100],{"class":71},[33,2962,2963],{"class":103}," TabPanelMount",[33,2965,107],{"class":75},[33,2967,2968],{"class":110},"activeTab",[33,2970,293],{"class":75},[33,2972,2973],{"class":110},"tabs",[33,2975,114],{"class":75},[33,2977,2978,2980],{"class":35,"line":61},[33,2979,120],{"class":71},[33,2981,187],{"class":75},[33,2983,2984,2986,2988],{"class":35,"line":68},[33,2985,193],{"class":75},[33,2987,197],{"class":196},[33,2989,200],{"class":75},[33,2991,2992,2995,2997,2999,3002,3004],{"class":35,"line":86},[33,2993,2994],{"class":75},"      {tabs.",[33,2996,959],{"class":103},[33,2998,915],{"class":75},[33,3000,3001],{"class":110},"tab",[33,3003,921],{"class":71},[33,3005,187],{"class":75},[33,3007,3008,3010,3012,3014,3016,3019,3022,3024,3026,3028,3031,3034],{"class":35,"line":91},[33,3009,709],{"class":75},[33,3011,1887],{"class":196},[33,3013,973],{"class":103},[33,3015,234],{"class":71},[33,3017,3018],{"class":75},"{tab.id} ",[33,3020,3021],{"class":103},"onClick",[33,3023,234],{"class":71},[33,3025,1540],{"class":75},[33,3027,324],{"class":71},[33,3029,3030],{"class":75}," tabs.",[33,3032,3033],{"class":103},"onChange",[33,3035,3036],{"class":75},"(tab.id)}>\n",[33,3038,3039],{"class":35,"line":97},[33,3040,3041],{"class":75},"          {tab.label}\n",[33,3043,3044,3047,3049],{"class":35,"line":117},[33,3045,3046],{"class":75},"        \u003C\u002F",[33,3048,1887],{"class":196},[33,3050,200],{"class":75},[33,3052,3053],{"class":35,"line":150},[33,3054,3055],{"class":75},"      ))}\n",[33,3057,3058,3061,3063,3066,3068,3070,3073],{"class":35,"line":156},[33,3059,3060],{"class":75},"      {activeTab ",[33,3062,1110],{"class":71},[33,3064,3065],{"class":82}," 'overview'",[33,3067,526],{"class":71},[33,3069,129],{"class":75},[33,3071,3072],{"class":132},"OverviewPanel",[33,3074,3075],{"class":75}," \u002F>}\n",[33,3077,3078,3080,3082,3085,3088,3090,3093],{"class":35,"line":161},[33,3079,3060],{"class":75},[33,3081,1110],{"class":71},[33,3083,3084],{"class":82}," 'details'",[33,3086,3087],{"class":71},"  &&",[33,3089,129],{"class":75},[33,3091,3092],{"class":132},"DetailsPanel",[33,3094,3075],{"class":75},[33,3096,3097,3099,3101,3104,3106,3108,3111],{"class":35,"line":167},[33,3098,3060],{"class":75},[33,3100,1110],{"class":71},[33,3102,3103],{"class":82}," 'reviews'",[33,3105,3087],{"class":71},[33,3107,129],{"class":75},[33,3109,3110],{"class":132},"ReviewsPanel",[33,3112,3075],{"class":75},[33,3114,3115,3118],{"class":35,"line":182},[33,3116,3117],{"class":75},"      {",[33,3119,3120],{"class":39},"\u002F* Only the active panel exists in the DOM at any time.\n",[33,3122,3123],{"class":35,"line":190},[33,3124,3125],{"class":39},"          Switching tabs unmounts the old panel (state lost, effects cleaned up)\n",[33,3127,3128,3131],{"class":35,"line":203},[33,3129,3130],{"class":39},"          and mounts the new one (fresh state, effects re-run). *\u002F",[33,3132,153],{"class":75},[33,3134,3135,3137,3139],{"class":35,"line":218},[33,3136,251],{"class":75},[33,3138,197],{"class":196},[33,3140,200],{"class":75},[33,3142,3143],{"class":35,"line":248},[33,3144,261],{"class":75},[33,3146,3147],{"class":35,"line":258},[33,3148,153],{"class":75},[33,3150,3151],{"class":35,"line":264},[33,3152,65],{"emptyLinePlaceholder":64},[33,3154,3155],{"class":35,"line":269},[33,3156,3157],{"class":39},"\u002F\u002F ── SHOW\u002FHIDE: keep mounted, toggle visibility via CSS ──\n",[33,3159,3160,3162,3165,3167,3169,3171,3173],{"class":35,"line":274},[33,3161,100],{"class":71},[33,3163,3164],{"class":103}," TabPanelShowHide",[33,3166,107],{"class":75},[33,3168,2968],{"class":110},[33,3170,293],{"class":75},[33,3172,2973],{"class":110},[33,3174,114],{"class":75},[33,3176,3177,3179],{"class":35,"line":280},[33,3178,120],{"class":71},[33,3180,187],{"class":75},[33,3182,3183,3185,3187],{"class":35,"line":301},[33,3184,193],{"class":75},[33,3186,197],{"class":196},[33,3188,200],{"class":75},[33,3190,3191,3193,3195,3197,3199,3201],{"class":35,"line":308},[33,3192,2994],{"class":75},[33,3194,959],{"class":103},[33,3196,915],{"class":75},[33,3198,3001],{"class":110},[33,3200,921],{"class":71},[33,3202,187],{"class":75},[33,3204,3205,3207,3209,3211,3213,3215,3217,3219,3221,3223,3225,3227],{"class":35,"line":318},[33,3206,709],{"class":75},[33,3208,1887],{"class":196},[33,3210,973],{"class":103},[33,3212,234],{"class":71},[33,3214,3018],{"class":75},[33,3216,3021],{"class":103},[33,3218,234],{"class":71},[33,3220,1540],{"class":75},[33,3222,324],{"class":71},[33,3224,3030],{"class":75},[33,3226,3033],{"class":103},[33,3228,3036],{"class":75},[33,3230,3231],{"class":35,"line":330},[33,3232,3041],{"class":75},[33,3234,3235,3237,3239],{"class":35,"line":339},[33,3236,3046],{"class":75},[33,3238,1887],{"class":196},[33,3240,200],{"class":75},[33,3242,3243],{"class":35,"line":367},[33,3244,3055],{"class":75},[33,3246,3247,3249,3251,3254,3256,3259,3261,3263,3265,3268,3271,3274],{"class":35,"line":392},[33,3248,206],{"class":75},[33,3250,197],{"class":196},[33,3252,3253],{"class":103}," style",[33,3255,234],{"class":71},[33,3257,3258],{"class":75},"{{ display: activeTab ",[33,3260,1110],{"class":71},[33,3262,3065],{"class":82},[33,3264,702],{"class":71},[33,3266,3267],{"class":82}," 'block'",[33,3269,3270],{"class":71}," :",[33,3272,3273],{"class":82}," 'none'",[33,3275,3276],{"class":75}," }}>\n",[33,3278,3279,3281,3283],{"class":35,"line":412},[33,3280,709],{"class":75},[33,3282,3072],{"class":132},[33,3284,147],{"class":75},[33,3286,3287,3289,3291],{"class":35,"line":430},[33,3288,1725],{"class":75},[33,3290,197],{"class":196},[33,3292,200],{"class":75},[33,3294,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317],{"class":35,"line":436},[33,3296,206],{"class":75},[33,3298,197],{"class":196},[33,3300,3253],{"class":103},[33,3302,234],{"class":71},[33,3304,3258],{"class":75},[33,3306,1110],{"class":71},[33,3308,3084],{"class":82},[33,3310,702],{"class":71},[33,3312,3267],{"class":82},[33,3314,3270],{"class":71},[33,3316,3273],{"class":82},[33,3318,3276],{"class":75},[33,3320,3321,3323,3325],{"class":35,"line":442},[33,3322,709],{"class":75},[33,3324,3092],{"class":132},[33,3326,147],{"class":75},[33,3328,3329,3331,3333],{"class":35,"line":451},[33,3330,1725],{"class":75},[33,3332,197],{"class":196},[33,3334,200],{"class":75},[33,3336,3337,3339,3341,3343,3345,3347,3349,3351,3353,3355,3357,3359],{"class":35,"line":456},[33,3338,206],{"class":75},[33,3340,197],{"class":196},[33,3342,3253],{"class":103},[33,3344,234],{"class":71},[33,3346,3258],{"class":75},[33,3348,1110],{"class":71},[33,3350,3103],{"class":82},[33,3352,702],{"class":71},[33,3354,3267],{"class":82},[33,3356,3270],{"class":71},[33,3358,3273],{"class":82},[33,3360,3276],{"class":75},[33,3362,3363,3365,3367],{"class":35,"line":462},[33,3364,709],{"class":75},[33,3366,3110],{"class":132},[33,3368,147],{"class":75},[33,3370,3371,3373,3375],{"class":35,"line":468},[33,3372,1725],{"class":75},[33,3374,197],{"class":196},[33,3376,200],{"class":75},[33,3378,3379,3381],{"class":35,"line":826},[33,3380,3117],{"class":75},[33,3382,3383],{"class":39},"\u002F* All panels remain mounted — state persists across tab switches.\n",[33,3385,3386,3389],{"class":35,"line":847},[33,3387,3388],{"class":39},"          But: all panels' effects run simultaneously, all are in the DOM (heavier). *\u002F",[33,3390,153],{"class":75},[33,3392,3393,3395,3397],{"class":35,"line":853},[33,3394,251],{"class":75},[33,3396,197],{"class":196},[33,3398,200],{"class":75},[33,3400,3401],{"class":35,"line":862},[33,3402,261],{"class":75},[33,3404,3405],{"class":35,"line":867},[33,3406,153],{"class":75},[33,3408,3409],{"class":35,"line":872},[33,3410,65],{"emptyLinePlaceholder":64},[33,3412,3413],{"class":35,"line":877},[33,3414,3415],{"class":39},"\u002F\u002F ── WHEN TO USE WHICH ──\n",[33,3417,3418],{"class":35,"line":883},[33,3419,3420],{"class":39},"\u002F\u002F MOUNT\u002FUNMOUNT (conditional render):\n",[33,3422,3423],{"class":35,"line":897},[33,3424,3425],{"class":39},"\u002F\u002F   ✓ Lightweight panels, no expensive state to preserve\n",[33,3427,3428],{"class":35,"line":936},[33,3429,3430],{"class":39},"\u002F\u002F   ✓ Panels with heavy initial data fetching (only fetch the visible one)\n",[33,3432,3433],{"class":35,"line":943},[33,3434,3435],{"class":39},"\u002F\u002F   ✓ Forms that should reset on tab switch\n",[33,3437,3438],{"class":35,"line":953},[33,3439,3440],{"class":39},"\u002F\u002F   ✗ Bad when: user loses in-progress form data on tab switch\n",[33,3442,3443],{"class":35,"line":986},[33,3444,65],{"emptyLinePlaceholder":64},[33,3446,3447],{"class":35,"line":1011},[33,3448,3449],{"class":39},"\u002F\u002F SHOW\u002FHIDE (CSS display):\n",[33,3451,3452],{"class":35,"line":1022},[33,3453,3454],{"class":39},"\u002F\u002F   ✓ Preserve component state (scroll position, form input, expanded accordions)\n",[33,3456,3457],{"class":35,"line":1028},[33,3458,3459],{"class":39},"\u002F\u002F   ✓ Avoid re-running expensive effects (data fetching, subscriptions)\n",[33,3461,3462],{"class":35,"line":1037},[33,3463,3464],{"class":39},"\u002F\u002F   ✓ Heavy components where mount cost is high (charts, editors, maps)\n",[33,3466,3467],{"class":35,"line":1042},[33,3468,3469],{"class":39},"\u002F\u002F   ✗ Bad when: many panels — all are in DOM simultaneously, bloating memory\n",[33,3471,3472],{"class":35,"line":2861},[33,3473,3474],{"class":39},"\u002F\u002F   ✗ Bad when: effects should not run when panel is not visible (analytics, polling)\n",[33,3476,3477],{"class":35,"line":2866},[33,3478,65],{"emptyLinePlaceholder":64},[33,3480,3481],{"class":35,"line":2871},[33,3482,3483],{"class":39},"\u002F\u002F COMPLEX: hybrid — keep recently-visited panels mounted, unmount distant ones\n",[33,3485,3486,3488,3491,3493,3495,3497,3500],{"class":35,"line":2890},[33,3487,100],{"class":71},[33,3489,3490],{"class":103}," SmartTabPanels",[33,3492,107],{"class":75},[33,3494,2968],{"class":110},[33,3496,293],{"class":75},[33,3498,3499],{"class":110},"tabIds",[33,3501,114],{"class":75},[33,3503,3504,3506,3508,3511,3513,3516,3518,3520,3522,3524,3527,3530],{"class":35,"line":2912},[33,3505,900],{"class":71},[33,3507,1376],{"class":75},[33,3509,3510],{"class":132},"mountedTabs",[33,3512,293],{"class":75},[33,3514,3515],{"class":132},"setMountedTabs",[33,3517,1387],{"class":75},[33,3519,234],{"class":71},[33,3521,1392],{"class":103},[33,3523,915],{"class":75},[33,3525,3526],{"class":71},"new",[33,3528,3529],{"class":103}," Set",[33,3531,3532],{"class":75},"([activeTab]))\n",[33,3534,3535],{"class":35,"line":2922},[33,3536,65],{"emptyLinePlaceholder":64},[33,3538,3540,3542,3544,3546],{"class":35,"line":3539},64,[33,3541,1408],{"class":103},[33,3543,1411],{"class":75},[33,3545,324],{"class":71},[33,3547,327],{"class":75},[33,3549,3551,3554,3556,3559,3561,3563,3565,3568,3570],{"class":35,"line":3550},65,[33,3552,3553],{"class":103},"    setMountedTabs",[33,3555,915],{"class":75},[33,3557,3558],{"class":110},"prev",[33,3560,921],{"class":71},[33,3562,2656],{"class":71},[33,3564,3529],{"class":103},[33,3566,3567],{"class":75},"([",[33,3569,2616],{"class":71},[33,3571,3572],{"class":75},"prev, activeTab]))\n",[33,3574,3576],{"class":35,"line":3575},66,[33,3577,3578],{"class":39},"    \u002F\u002F Once a tab has been visited, keep it mounted (preserve state).\n",[33,3580,3582],{"class":35,"line":3581},67,[33,3583,3584],{"class":39},"    \u002F\u002F Only the active tab is visible; previously-visited tabs are display:none.\n",[33,3586,3588],{"class":35,"line":3587},68,[33,3589,3590],{"class":75},"  }, [activeTab])\n",[33,3592,3594],{"class":35,"line":3593},69,[33,3595,65],{"emptyLinePlaceholder":64},[33,3597,3599,3601],{"class":35,"line":3598},70,[33,3600,120],{"class":71},[33,3602,187],{"class":75},[33,3604,3606,3608,3610],{"class":35,"line":3605},71,[33,3607,193],{"class":75},[33,3609,197],{"class":196},[33,3611,200],{"class":75},[33,3613,3615,3618,3620,3622,3625,3627],{"class":35,"line":3614},72,[33,3616,3617],{"class":75},"      {tabIds.",[33,3619,959],{"class":103},[33,3621,915],{"class":75},[33,3623,3624],{"class":110},"tabId",[33,3626,921],{"class":71},[33,3628,327],{"class":75},[33,3630,3632,3635,3637,3639,3642,3645,3648,3650,3652],{"class":35,"line":3631},73,[33,3633,3634],{"class":71},"        if",[33,3636,2642],{"class":75},[33,3638,2645],{"class":71},[33,3640,3641],{"class":75},"mountedTabs.",[33,3643,3644],{"class":103},"has",[33,3646,3647],{"class":75},"(tabId)) ",[33,3649,351],{"class":71},[33,3651,731],{"class":132},[33,3653,3654],{"class":39},"  \u002F\u002F never-visited: don't mount\n",[33,3656,3658,3661,3664,3666,3669,3671],{"class":35,"line":3657},74,[33,3659,3660],{"class":71},"        const",[33,3662,3663],{"class":132}," isVisible",[33,3665,906],{"class":71},[33,3667,3668],{"class":75}," tabId ",[33,3670,1110],{"class":71},[33,3672,3673],{"class":75}," activeTab\n",[33,3675,3677,3680],{"class":35,"line":3676},75,[33,3678,3679],{"class":71},"        return",[33,3681,187],{"class":75},[33,3683,3685,3687,3689,3691,3693,3696,3699,3701,3704,3706,3708,3710,3712],{"class":35,"line":3684},76,[33,3686,1681],{"class":75},[33,3688,197],{"class":196},[33,3690,973],{"class":103},[33,3692,234],{"class":71},[33,3694,3695],{"class":75},"{tabId} ",[33,3697,3698],{"class":103},"style",[33,3700,234],{"class":71},[33,3702,3703],{"class":75},"{{ display: isVisible ",[33,3705,126],{"class":71},[33,3707,3267],{"class":82},[33,3709,3270],{"class":71},[33,3711,3273],{"class":82},[33,3713,3276],{"class":75},[33,3715,3717,3719,3722,3725,3727],{"class":35,"line":3716},77,[33,3718,1695],{"class":75},[33,3720,3721],{"class":132},"TabContent",[33,3723,3724],{"class":103}," tabId",[33,3726,234],{"class":71},[33,3728,3729],{"class":75},"{tabId} \u002F>\n",[33,3731,3733,3735,3737],{"class":35,"line":3732},78,[33,3734,1711],{"class":75},[33,3736,197],{"class":196},[33,3738,200],{"class":75},[33,3740,3742],{"class":35,"line":3741},79,[33,3743,3744],{"class":75},"        )\n",[33,3746,3748],{"class":35,"line":3747},80,[33,3749,3750],{"class":75},"      })}\n",[33,3752,3754,3756,3758],{"class":35,"line":3753},81,[33,3755,251],{"class":75},[33,3757,197],{"class":196},[33,3759,200],{"class":75},[33,3761,3763],{"class":35,"line":3762},82,[33,3764,261],{"class":75},[33,3766,3768],{"class":35,"line":3767},83,[33,3769,153],{"class":75},[33,3771,3773],{"class":35,"line":3772},84,[33,3774,65],{"emptyLinePlaceholder":64},[33,3776,3778],{"class":35,"line":3777},85,[33,3779,3780],{"class":39},"\u002F\u002F ANTI-PATTERN: unmounting to \"reset\" a form when the user just switched tabs\n",[33,3782,3784,3786,3789,3791,3794],{"class":35,"line":3783},86,[33,3785,100],{"class":71},[33,3787,3788],{"class":103}," BadSettingsPage",[33,3790,107],{"class":75},[33,3792,3793],{"class":110},"activeSection",[33,3795,114],{"class":75},[33,3797,3799,3801],{"class":35,"line":3798},87,[33,3800,120],{"class":71},[33,3802,187],{"class":75},[33,3804,3806,3808,3810],{"class":35,"line":3805},88,[33,3807,193],{"class":75},[33,3809,197],{"class":196},[33,3811,200],{"class":75},[33,3813,3815,3818,3820,3823,3826,3828,3831],{"class":35,"line":3814},89,[33,3816,3817],{"class":75},"      {activeSection ",[33,3819,1110],{"class":71},[33,3821,3822],{"class":82}," 'profile'",[33,3824,3825],{"class":71},"   &&",[33,3827,129],{"class":75},[33,3829,3830],{"class":132},"ProfileForm",[33,3832,3075],{"class":75},[33,3834,3836,3838,3840,3843,3845,3847,3850],{"class":35,"line":3835},90,[33,3837,3817],{"class":75},[33,3839,1110],{"class":71},[33,3841,3842],{"class":82}," 'security'",[33,3844,3087],{"class":71},[33,3846,129],{"class":75},[33,3848,3849],{"class":132},"SecurityForm",[33,3851,3075],{"class":75},[33,3853,3855,3857,3859,3862,3864,3866,3869],{"class":35,"line":3854},91,[33,3856,3817],{"class":75},[33,3858,1110],{"class":71},[33,3860,3861],{"class":82}," 'notifications'",[33,3863,526],{"class":71},[33,3865,129],{"class":75},[33,3867,3868],{"class":132},"NotificationForm",[33,3870,3075],{"class":75},[33,3872,3874,3876],{"class":35,"line":3873},92,[33,3875,3117],{"class":75},[33,3877,3878],{"class":39},"\u002F* User fills half the ProfileForm, clicks Security to check something,\n",[33,3880,3882],{"class":35,"line":3881},93,[33,3883,3884],{"class":39},"          clicks back to Profile → form is BLANK (unmounted + remounted = state lost).\n",[33,3886,3888,3891],{"class":35,"line":3887},94,[33,3889,3890],{"class":39},"          Use show\u002Fhide or persist form state to parent\u002FContext instead. *\u002F",[33,3892,153],{"class":75},[33,3894,3896,3898,3900],{"class":35,"line":3895},95,[33,3897,251],{"class":75},[33,3899,197],{"class":196},[33,3901,200],{"class":75},[33,3903,3905],{"class":35,"line":3904},96,[33,3906,261],{"class":75},[33,3908,3910],{"class":35,"line":3909},97,[33,3911,153],{"class":75},[14,3913,3915],{"id":3914},"extracting-conditional-logic-to-variables-and-functions","Extracting Conditional Logic to Variables and Functions",[19,3917,3919],{"filename":3918,"language":22},"extracting_conditionals.js",[24,3920,3922],{"className":26,"code":3921,"language":22,"meta":28,"style":28},"import { useState, useMemo } from 'react'\n\n\u002F\u002F ANTI-PATTERN: inline complex conditionals in JSX — unreadable\nfunction DashboardBad({ user, permissions, notifications, isLoading }) {\n  return (\n    \u003Cdiv>\n      {(isLoading && !user) ? (\n        \u003CSpinner \u002F>\n      ) : (\n        (user && (permissions.includes('admin') || permissions.includes('editor')) && notifications.filter(n => n.unread).length > 0) ? (\n          \u003CAdminNotificationBar notifications={notifications.filter(n => n.unread)} \u002F>\n        ) : null\n      )}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F CORRECT: extract to named variables — self-documenting, testable\nfunction DashboardGood({ user, permissions, notifications, isLoading }) {\n  const showLoadingSpinner = isLoading && !user\n  const unreadNotifications = notifications.filter(n => n.unread)\n  const canManageContent = permissions.includes('admin') || permissions.includes('editor')\n  const showNotificationBar = user && canManageContent && unreadNotifications.length > 0\n\n  return (\n    \u003Cdiv>\n      {showLoadingSpinner && \u003CSpinner \u002F>}\n      {showNotificationBar && \u003CAdminNotificationBar notifications={unreadNotifications} \u002F>}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F COMPLEX: extract to functions for reusable conditional rendering logic\nfunction ProductCard({ product, user, isFavorite, onToggleFavorite }) {\n  const canReview = user && user.id !== product.sellerId && product.isPurchased\n  const discountPercent = product.originalPrice\n    ? Math.round((1 - product.price \u002F product.originalPrice) * 100)\n    : 0\n  const showDiscount = discountPercent > 0 && discountPercent \u003C 100\n\n  function renderPrice() {\n    if (!showDiscount) return \u003Cspan className=\"price\">${product.price}\u003C\u002Fspan>\n    return (\n      \u003Cdiv className=\"price-group\">\n        \u003Cspan className=\"original-price\">${product.originalPrice}\u003C\u002Fspan>\n        \u003Cspan className=\"sale-price\">${product.price}\u003C\u002Fspan>\n        \u003Cspan className=\"discount-badge\">-{discountPercent}%\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    )\n  }\n\n  function renderActions() {\n    if (!user) return \u003CSignInToInteract \u002F>\n    return (\n      \u003Cdiv className=\"actions\">\n        \u003CFavoriteButton active={isFavorite} onClick={onToggleFavorite} \u002F>\n        {canReview && \u003CWriteReviewButton productId={product.id} \u002F>}\n      \u003C\u002Fdiv>\n    )\n  }\n\n  return (\n    \u003Carticle className=\"product-card\">\n      \u003Cimg src={product.image} alt={product.name} \u002F>\n      \u003Ch3>{product.name}\u003C\u002Fh3>\n      {renderPrice()}\n      {renderActions()}\n    \u003C\u002Farticle>\n  )\n}\n\n\u002F\u002F COMPLEX: useMemo for expensive conditional derivations\nfunction FilteredDataView({ data, filters, searchQuery }) {\n  const filteredData = useMemo(() => {\n    let result = data\n    if (searchQuery) {\n      result = result.filter(item =>\n        item.name.toLowerCase().includes(searchQuery.toLowerCase())\n      )\n    }\n    for (const [key, value] of Object.entries(filters)) {\n      if (value !== null && value !== undefined && value !== '') {\n        result = result.filter(item => item[key] === value)\n      }\n    }\n    return result\n  }, [data, filters, searchQuery])\n\n  const hasData = data.length > 0\n  const hasResults = filteredData.length > 0\n  const hasActiveFilters = Object.values(filters).some(v => v !== null && v !== '')\n\n  if (!hasData) return \u003CEmptyDataState \u002F>\n  if (!hasResults && hasActiveFilters) return \u003CNoMatchesState onClear={() => filters.clearAll()} \u002F>\n  if (!hasResults) return \u003CNoDataAfterSearchState query={searchQuery} \u002F>\n\n  return (\n    \u003Cul>\n      {filteredData.map(item => \u003CDataRow key={item.id} item={item} \u002F>)}\n    \u003C\u002Ful>\n  )\n}\n",[30,3923,3924,3935,3939,3944,3972,3978,3986,4003,4011,4019,4084,4110,4119,4123,4131,4135,4139,4143,4148,4173,4192,4214,4245,4274,4278,4284,4292,4305,4323,4331,4335,4339,4343,4348,4376,4403,4415,4452,4459,4484,4488,4499,4530,4536,4551,4571,4590,4610,4618,4622,4626,4630,4639,4658,4664,4679,4701,4721,4729,4733,4737,4741,4747,4763,4786,4799,4809,4818,4826,4830,4834,4838,4843,4866,4884,4897,4904,4924,4945,4950,4955,4988,5021,5046,5051,5055,5062,5067,5071,5089,5107,5151,5155,5175,5216,5241,5245,5251,5260,5293,5302,5307],{"__ignoreMap":28},[33,3925,3926,3928,3931,3933],{"class":35,"line":36},[33,3927,72],{"class":71},[33,3929,3930],{"class":75}," { useState, useMemo } ",[33,3932,79],{"class":71},[33,3934,83],{"class":82},[33,3936,3937],{"class":35,"line":43},[33,3938,65],{"emptyLinePlaceholder":64},[33,3940,3941],{"class":35,"line":49},[33,3942,3943],{"class":39},"\u002F\u002F ANTI-PATTERN: inline complex conditionals in JSX — unreadable\n",[33,3945,3946,3948,3951,3953,3955,3957,3960,3962,3965,3967,3970],{"class":35,"line":55},[33,3947,100],{"class":71},[33,3949,3950],{"class":103}," DashboardBad",[33,3952,107],{"class":75},[33,3954,1093],{"class":110},[33,3956,293],{"class":75},[33,3958,3959],{"class":110},"permissions",[33,3961,293],{"class":75},[33,3963,3964],{"class":110},"notifications",[33,3966,293],{"class":75},[33,3968,3969],{"class":110},"isLoading",[33,3971,114],{"class":75},[33,3973,3974,3976],{"class":35,"line":61},[33,3975,120],{"class":71},[33,3977,187],{"class":75},[33,3979,3980,3982,3984],{"class":35,"line":68},[33,3981,193],{"class":75},[33,3983,197],{"class":196},[33,3985,200],{"class":75},[33,3987,3988,3991,3993,3996,3999,4001],{"class":35,"line":86},[33,3989,3990],{"class":75},"      {(isLoading ",[33,3992,224],{"class":71},[33,3994,3995],{"class":71}," !",[33,3997,3998],{"class":75},"user) ",[33,4000,126],{"class":71},[33,4002,187],{"class":75},[33,4004,4005,4007,4009],{"class":35,"line":91},[33,4006,709],{"class":75},[33,4008,1124],{"class":132},[33,4010,147],{"class":75},[33,4012,4013,4015,4017],{"class":35,"line":97},[33,4014,726],{"class":75},[33,4016,139],{"class":71},[33,4018,187],{"class":75},[33,4020,4021,4024,4026,4029,4032,4034,4037,4039,4042,4045,4047,4049,4052,4055,4057,4060,4062,4064,4067,4069,4072,4074,4076,4078,4080,4082],{"class":35,"line":117},[33,4022,4023],{"class":75},"        (user ",[33,4025,224],{"class":71},[33,4027,4028],{"class":75}," (permissions.",[33,4030,4031],{"class":103},"includes",[33,4033,915],{"class":75},[33,4035,4036],{"class":82},"'admin'",[33,4038,1253],{"class":75},[33,4040,4041],{"class":71},"||",[33,4043,4044],{"class":75}," permissions.",[33,4046,4031],{"class":103},[33,4048,915],{"class":75},[33,4050,4051],{"class":82},"'editor'",[33,4053,4054],{"class":75},")) ",[33,4056,224],{"class":71},[33,4058,4059],{"class":75}," notifications.",[33,4061,912],{"class":103},[33,4063,915],{"class":75},[33,4065,4066],{"class":110},"n",[33,4068,921],{"class":71},[33,4070,4071],{"class":75}," n.unread).",[33,4073,523],{"class":132},[33,4075,613],{"class":71},[33,4077,616],{"class":132},[33,4079,1253],{"class":75},[33,4081,126],{"class":71},[33,4083,187],{"class":75},[33,4085,4086,4088,4091,4094,4096,4099,4101,4103,4105,4107],{"class":35,"line":150},[33,4087,1681],{"class":75},[33,4089,4090],{"class":132},"AdminNotificationBar",[33,4092,4093],{"class":103}," notifications",[33,4095,234],{"class":71},[33,4097,4098],{"class":75},"{notifications.",[33,4100,912],{"class":103},[33,4102,915],{"class":75},[33,4104,4066],{"class":110},[33,4106,921],{"class":71},[33,4108,4109],{"class":75}," n.unread)} \u002F>\n",[33,4111,4112,4115,4117],{"class":35,"line":156},[33,4113,4114],{"class":75},"        ) ",[33,4116,139],{"class":71},[33,4118,1199],{"class":132},[33,4120,4121],{"class":35,"line":161},[33,4122,850],{"class":75},[33,4124,4125,4127,4129],{"class":35,"line":167},[33,4126,251],{"class":75},[33,4128,197],{"class":196},[33,4130,200],{"class":75},[33,4132,4133],{"class":35,"line":182},[33,4134,261],{"class":75},[33,4136,4137],{"class":35,"line":190},[33,4138,153],{"class":75},[33,4140,4141],{"class":35,"line":203},[33,4142,65],{"emptyLinePlaceholder":64},[33,4144,4145],{"class":35,"line":218},[33,4146,4147],{"class":39},"\u002F\u002F CORRECT: extract to named variables — self-documenting, testable\n",[33,4149,4150,4152,4155,4157,4159,4161,4163,4165,4167,4169,4171],{"class":35,"line":248},[33,4151,100],{"class":71},[33,4153,4154],{"class":103}," DashboardGood",[33,4156,107],{"class":75},[33,4158,1093],{"class":110},[33,4160,293],{"class":75},[33,4162,3959],{"class":110},[33,4164,293],{"class":75},[33,4166,3964],{"class":110},[33,4168,293],{"class":75},[33,4170,3969],{"class":110},[33,4172,114],{"class":75},[33,4174,4175,4177,4180,4182,4185,4187,4189],{"class":35,"line":258},[33,4176,900],{"class":71},[33,4178,4179],{"class":132}," showLoadingSpinner",[33,4181,906],{"class":71},[33,4183,4184],{"class":75}," isLoading ",[33,4186,224],{"class":71},[33,4188,3995],{"class":71},[33,4190,4191],{"class":75},"user\n",[33,4193,4194,4196,4199,4201,4203,4205,4207,4209,4211],{"class":35,"line":264},[33,4195,900],{"class":71},[33,4197,4198],{"class":132}," unreadNotifications",[33,4200,906],{"class":71},[33,4202,4059],{"class":75},[33,4204,912],{"class":103},[33,4206,915],{"class":75},[33,4208,4066],{"class":110},[33,4210,921],{"class":71},[33,4212,4213],{"class":75}," n.unread)\n",[33,4215,4216,4218,4221,4223,4225,4227,4229,4231,4233,4235,4237,4239,4241,4243],{"class":35,"line":269},[33,4217,900],{"class":71},[33,4219,4220],{"class":132}," canManageContent",[33,4222,906],{"class":71},[33,4224,4044],{"class":75},[33,4226,4031],{"class":103},[33,4228,915],{"class":75},[33,4230,4036],{"class":82},[33,4232,1253],{"class":75},[33,4234,4041],{"class":71},[33,4236,4044],{"class":75},[33,4238,4031],{"class":103},[33,4240,915],{"class":75},[33,4242,4051],{"class":82},[33,4244,933],{"class":75},[33,4246,4247,4249,4252,4254,4257,4259,4262,4264,4267,4269,4271],{"class":35,"line":274},[33,4248,900],{"class":71},[33,4250,4251],{"class":132}," showNotificationBar",[33,4253,906],{"class":71},[33,4255,4256],{"class":75}," user ",[33,4258,224],{"class":71},[33,4260,4261],{"class":75}," canManageContent ",[33,4263,224],{"class":71},[33,4265,4266],{"class":75}," unreadNotifications.",[33,4268,523],{"class":132},[33,4270,613],{"class":71},[33,4272,4273],{"class":132}," 0\n",[33,4275,4276],{"class":35,"line":280},[33,4277,65],{"emptyLinePlaceholder":64},[33,4279,4280,4282],{"class":35,"line":301},[33,4281,120],{"class":71},[33,4283,187],{"class":75},[33,4285,4286,4288,4290],{"class":35,"line":308},[33,4287,193],{"class":75},[33,4289,197],{"class":196},[33,4291,200],{"class":75},[33,4293,4294,4297,4299,4301,4303],{"class":35,"line":318},[33,4295,4296],{"class":75},"      {showLoadingSpinner ",[33,4298,224],{"class":71},[33,4300,129],{"class":75},[33,4302,1124],{"class":132},[33,4304,3075],{"class":75},[33,4306,4307,4310,4312,4314,4316,4318,4320],{"class":35,"line":330},[33,4308,4309],{"class":75},"      {showNotificationBar ",[33,4311,224],{"class":71},[33,4313,129],{"class":75},[33,4315,4090],{"class":132},[33,4317,4093],{"class":103},[33,4319,234],{"class":71},[33,4321,4322],{"class":75},"{unreadNotifications} \u002F>}\n",[33,4324,4325,4327,4329],{"class":35,"line":339},[33,4326,251],{"class":75},[33,4328,197],{"class":196},[33,4330,200],{"class":75},[33,4332,4333],{"class":35,"line":367},[33,4334,261],{"class":75},[33,4336,4337],{"class":35,"line":392},[33,4338,153],{"class":75},[33,4340,4341],{"class":35,"line":412},[33,4342,65],{"emptyLinePlaceholder":64},[33,4344,4345],{"class":35,"line":430},[33,4346,4347],{"class":39},"\u002F\u002F COMPLEX: extract to functions for reusable conditional rendering logic\n",[33,4349,4350,4352,4355,4357,4360,4362,4364,4366,4369,4371,4374],{"class":35,"line":436},[33,4351,100],{"class":71},[33,4353,4354],{"class":103}," ProductCard",[33,4356,107],{"class":75},[33,4358,4359],{"class":110},"product",[33,4361,293],{"class":75},[33,4363,1093],{"class":110},[33,4365,293],{"class":75},[33,4367,4368],{"class":110},"isFavorite",[33,4370,293],{"class":75},[33,4372,4373],{"class":110},"onToggleFavorite",[33,4375,114],{"class":75},[33,4377,4378,4380,4383,4385,4387,4389,4392,4395,4398,4400],{"class":35,"line":442},[33,4379,900],{"class":71},[33,4381,4382],{"class":132}," canReview",[33,4384,906],{"class":71},[33,4386,4256],{"class":75},[33,4388,224],{"class":71},[33,4390,4391],{"class":75}," user.id ",[33,4393,4394],{"class":71},"!==",[33,4396,4397],{"class":75}," product.sellerId ",[33,4399,224],{"class":71},[33,4401,4402],{"class":75}," product.isPurchased\n",[33,4404,4405,4407,4410,4412],{"class":35,"line":451},[33,4406,900],{"class":71},[33,4408,4409],{"class":132}," discountPercent",[33,4411,906],{"class":71},[33,4413,4414],{"class":75}," product.originalPrice\n",[33,4416,4417,4420,4423,4426,4429,4432,4435,4438,4441,4444,4447,4450],{"class":35,"line":456},[33,4418,4419],{"class":71},"    ?",[33,4421,4422],{"class":75}," Math.",[33,4424,4425],{"class":103},"round",[33,4427,4428],{"class":75},"((",[33,4430,4431],{"class":132},"1",[33,4433,4434],{"class":71}," -",[33,4436,4437],{"class":75}," product.price ",[33,4439,4440],{"class":71},"\u002F",[33,4442,4443],{"class":75}," product.originalPrice) ",[33,4445,4446],{"class":71},"*",[33,4448,4449],{"class":132}," 100",[33,4451,933],{"class":75},[33,4453,4454,4457],{"class":35,"line":462},[33,4455,4456],{"class":71},"    :",[33,4458,4273],{"class":132},[33,4460,4461,4463,4466,4468,4471,4473,4475,4477,4479,4481],{"class":35,"line":468},[33,4462,900],{"class":71},[33,4464,4465],{"class":132}," showDiscount",[33,4467,906],{"class":71},[33,4469,4470],{"class":75}," discountPercent ",[33,4472,927],{"class":71},[33,4474,616],{"class":132},[33,4476,526],{"class":71},[33,4478,4470],{"class":75},[33,4480,1804],{"class":71},[33,4482,4483],{"class":132}," 100\n",[33,4485,4486],{"class":35,"line":826},[33,4487,65],{"emptyLinePlaceholder":64},[33,4489,4490,4493,4496],{"class":35,"line":847},[33,4491,4492],{"class":71},"  function",[33,4494,4495],{"class":103}," renderPrice",[33,4497,4498],{"class":75},"() {\n",[33,4500,4501,4503,4505,4507,4510,4512,4514,4516,4518,4520,4523,4526,4528],{"class":35,"line":853},[33,4502,1420],{"class":71},[33,4504,2642],{"class":75},[33,4506,2645],{"class":71},[33,4508,4509],{"class":75},"showDiscount) ",[33,4511,351],{"class":71},[33,4513,129],{"class":75},[33,4515,33],{"class":196},[33,4517,231],{"class":103},[33,4519,234],{"class":71},[33,4521,4522],{"class":82},"\"price\"",[33,4524,4525],{"class":75},">${product.price}\u003C\u002F",[33,4527,33],{"class":196},[33,4529,200],{"class":75},[33,4531,4532,4534],{"class":35,"line":862},[33,4533,1607],{"class":71},[33,4535,187],{"class":75},[33,4537,4538,4540,4542,4544,4546,4549],{"class":35,"line":867},[33,4539,206],{"class":75},[33,4541,197],{"class":196},[33,4543,231],{"class":103},[33,4545,234],{"class":71},[33,4547,4548],{"class":82},"\"price-group\"",[33,4550,200],{"class":75},[33,4552,4553,4555,4557,4559,4561,4564,4567,4569],{"class":35,"line":872},[33,4554,709],{"class":75},[33,4556,33],{"class":196},[33,4558,231],{"class":103},[33,4560,234],{"class":71},[33,4562,4563],{"class":82},"\"original-price\"",[33,4565,4566],{"class":75},">${product.originalPrice}\u003C\u002F",[33,4568,33],{"class":196},[33,4570,200],{"class":75},[33,4572,4573,4575,4577,4579,4581,4584,4586,4588],{"class":35,"line":877},[33,4574,709],{"class":75},[33,4576,33],{"class":196},[33,4578,231],{"class":103},[33,4580,234],{"class":71},[33,4582,4583],{"class":82},"\"sale-price\"",[33,4585,4525],{"class":75},[33,4587,33],{"class":196},[33,4589,200],{"class":75},[33,4591,4592,4594,4596,4598,4600,4603,4606,4608],{"class":35,"line":883},[33,4593,709],{"class":75},[33,4595,33],{"class":196},[33,4597,231],{"class":103},[33,4599,234],{"class":71},[33,4601,4602],{"class":82},"\"discount-badge\"",[33,4604,4605],{"class":75},">-{discountPercent}%\u003C\u002F",[33,4607,33],{"class":196},[33,4609,200],{"class":75},[33,4611,4612,4614,4616],{"class":35,"line":897},[33,4613,1725],{"class":75},[33,4615,197],{"class":196},[33,4617,200],{"class":75},[33,4619,4620],{"class":35,"line":936},[33,4621,1734],{"class":75},[33,4623,4624],{"class":35,"line":943},[33,4625,1634],{"class":75},[33,4627,4628],{"class":35,"line":953},[33,4629,65],{"emptyLinePlaceholder":64},[33,4631,4632,4634,4637],{"class":35,"line":986},[33,4633,4492],{"class":71},[33,4635,4636],{"class":103}," renderActions",[33,4638,4498],{"class":75},[33,4640,4641,4643,4645,4647,4649,4651,4653,4656],{"class":35,"line":1011},[33,4642,1420],{"class":71},[33,4644,2642],{"class":75},[33,4646,2645],{"class":71},[33,4648,3998],{"class":75},[33,4650,351],{"class":71},[33,4652,129],{"class":75},[33,4654,4655],{"class":132},"SignInToInteract",[33,4657,147],{"class":75},[33,4659,4660,4662],{"class":35,"line":1022},[33,4661,1607],{"class":71},[33,4663,187],{"class":75},[33,4665,4666,4668,4670,4672,4674,4677],{"class":35,"line":1028},[33,4667,206],{"class":75},[33,4669,197],{"class":196},[33,4671,231],{"class":103},[33,4673,234],{"class":71},[33,4675,4676],{"class":82},"\"actions\"",[33,4678,200],{"class":75},[33,4680,4681,4683,4686,4689,4691,4694,4696,4698],{"class":35,"line":1037},[33,4682,709],{"class":75},[33,4684,4685],{"class":132},"FavoriteButton",[33,4687,4688],{"class":103}," active",[33,4690,234],{"class":71},[33,4692,4693],{"class":75},"{isFavorite} ",[33,4695,3021],{"class":103},[33,4697,234],{"class":71},[33,4699,4700],{"class":75},"{onToggleFavorite} \u002F>\n",[33,4702,4703,4706,4708,4710,4713,4716,4718],{"class":35,"line":1042},[33,4704,4705],{"class":75},"        {canReview ",[33,4707,224],{"class":71},[33,4709,129],{"class":75},[33,4711,4712],{"class":132},"WriteReviewButton",[33,4714,4715],{"class":103}," productId",[33,4717,234],{"class":71},[33,4719,4720],{"class":75},"{product.id} \u002F>}\n",[33,4722,4723,4725,4727],{"class":35,"line":2861},[33,4724,1725],{"class":75},[33,4726,197],{"class":196},[33,4728,200],{"class":75},[33,4730,4731],{"class":35,"line":2866},[33,4732,1734],{"class":75},[33,4734,4735],{"class":35,"line":2871},[33,4736,1634],{"class":75},[33,4738,4739],{"class":35,"line":2890},[33,4740,65],{"emptyLinePlaceholder":64},[33,4742,4743,4745],{"class":35,"line":2912},[33,4744,120],{"class":71},[33,4746,187],{"class":75},[33,4748,4749,4751,4754,4756,4758,4761],{"class":35,"line":2922},[33,4750,193],{"class":75},[33,4752,4753],{"class":196},"article",[33,4755,231],{"class":103},[33,4757,234],{"class":71},[33,4759,4760],{"class":82},"\"product-card\"",[33,4762,200],{"class":75},[33,4764,4765,4767,4770,4773,4775,4778,4781,4783],{"class":35,"line":3539},[33,4766,206],{"class":75},[33,4768,4769],{"class":196},"img",[33,4771,4772],{"class":103}," src",[33,4774,234],{"class":71},[33,4776,4777],{"class":75},"{product.image} ",[33,4779,4780],{"class":103},"alt",[33,4782,234],{"class":71},[33,4784,4785],{"class":75},"{product.name} \u002F>\n",[33,4787,4788,4790,4792,4795,4797],{"class":35,"line":3550},[33,4789,206],{"class":75},[33,4791,1750],{"class":196},[33,4793,4794],{"class":75},">{product.name}\u003C\u002F",[33,4796,1750],{"class":196},[33,4798,200],{"class":75},[33,4800,4801,4803,4806],{"class":35,"line":3575},[33,4802,3117],{"class":75},[33,4804,4805],{"class":103},"renderPrice",[33,4807,4808],{"class":75},"()}\n",[33,4810,4811,4813,4816],{"class":35,"line":3581},[33,4812,3117],{"class":75},[33,4814,4815],{"class":103},"renderActions",[33,4817,4808],{"class":75},[33,4819,4820,4822,4824],{"class":35,"line":3587},[33,4821,251],{"class":75},[33,4823,4753],{"class":196},[33,4825,200],{"class":75},[33,4827,4828],{"class":35,"line":3593},[33,4829,261],{"class":75},[33,4831,4832],{"class":35,"line":3598},[33,4833,153],{"class":75},[33,4835,4836],{"class":35,"line":3605},[33,4837,65],{"emptyLinePlaceholder":64},[33,4839,4840],{"class":35,"line":3614},[33,4841,4842],{"class":39},"\u002F\u002F COMPLEX: useMemo for expensive conditional derivations\n",[33,4844,4845,4847,4850,4852,4854,4856,4859,4861,4864],{"class":35,"line":3631},[33,4846,100],{"class":71},[33,4848,4849],{"class":103}," FilteredDataView",[33,4851,107],{"class":75},[33,4853,296],{"class":110},[33,4855,293],{"class":75},[33,4857,4858],{"class":110},"filters",[33,4860,293],{"class":75},[33,4862,4863],{"class":110},"searchQuery",[33,4865,114],{"class":75},[33,4867,4868,4870,4873,4875,4878,4880,4882],{"class":35,"line":3657},[33,4869,900],{"class":71},[33,4871,4872],{"class":132}," filteredData",[33,4874,906],{"class":71},[33,4876,4877],{"class":103}," useMemo",[33,4879,1411],{"class":75},[33,4881,324],{"class":71},[33,4883,327],{"class":75},[33,4885,4886,4889,4892,4894],{"class":35,"line":3676},[33,4887,4888],{"class":71},"    let",[33,4890,4891],{"class":75}," result ",[33,4893,234],{"class":71},[33,4895,4896],{"class":75}," data\n",[33,4898,4899,4901],{"class":35,"line":3684},[33,4900,1420],{"class":71},[33,4902,4903],{"class":75}," (searchQuery) {\n",[33,4905,4906,4909,4911,4914,4916,4918,4921],{"class":35,"line":3716},[33,4907,4908],{"class":75},"      result ",[33,4910,234],{"class":71},[33,4912,4913],{"class":75}," result.",[33,4915,912],{"class":103},[33,4917,915],{"class":75},[33,4919,4920],{"class":110},"item",[33,4922,4923],{"class":71}," =>\n",[33,4925,4926,4929,4932,4935,4937,4940,4942],{"class":35,"line":3732},[33,4927,4928],{"class":75},"        item.name.",[33,4930,4931],{"class":103},"toLowerCase",[33,4933,4934],{"class":75},"().",[33,4936,4031],{"class":103},[33,4938,4939],{"class":75},"(searchQuery.",[33,4941,4931],{"class":103},[33,4943,4944],{"class":75},"())\n",[33,4946,4947],{"class":35,"line":3741},[33,4948,4949],{"class":75},"      )\n",[33,4951,4952],{"class":35,"line":3747},[33,4953,4954],{"class":75},"    }\n",[33,4956,4957,4960,4962,4964,4966,4969,4971,4974,4976,4979,4982,4985],{"class":35,"line":3753},[33,4958,4959],{"class":71},"    for",[33,4961,2642],{"class":75},[33,4963,2347],{"class":71},[33,4965,1376],{"class":75},[33,4967,4968],{"class":132},"key",[33,4970,293],{"class":75},[33,4972,4973],{"class":132},"value",[33,4975,1387],{"class":75},[33,4977,4978],{"class":71},"of",[33,4980,4981],{"class":75}," Object.",[33,4983,4984],{"class":103},"entries",[33,4986,4987],{"class":75},"(filters)) {\n",[33,4989,4990,4993,4996,4998,5000,5002,5005,5007,5010,5012,5014,5016,5019],{"class":35,"line":3762},[33,4991,4992],{"class":71},"      if",[33,4994,4995],{"class":75}," (value ",[33,4997,4394],{"class":71},[33,4999,731],{"class":132},[33,5001,526],{"class":71},[33,5003,5004],{"class":75}," value ",[33,5006,4394],{"class":71},[33,5008,5009],{"class":132}," undefined",[33,5011,526],{"class":71},[33,5013,5004],{"class":75},[33,5015,4394],{"class":71},[33,5017,5018],{"class":82}," ''",[33,5020,1602],{"class":75},[33,5022,5023,5026,5028,5030,5032,5034,5036,5038,5041,5043],{"class":35,"line":3767},[33,5024,5025],{"class":75},"        result ",[33,5027,234],{"class":71},[33,5029,4913],{"class":75},[33,5031,912],{"class":103},[33,5033,915],{"class":75},[33,5035,4920],{"class":110},[33,5037,921],{"class":71},[33,5039,5040],{"class":75}," item[key] ",[33,5042,1110],{"class":71},[33,5044,5045],{"class":75}," value)\n",[33,5047,5048],{"class":35,"line":3772},[33,5049,5050],{"class":75},"      }\n",[33,5052,5053],{"class":35,"line":3777},[33,5054,4954],{"class":75},[33,5056,5057,5059],{"class":35,"line":3783},[33,5058,1607],{"class":71},[33,5060,5061],{"class":75}," result\n",[33,5063,5064],{"class":35,"line":3798},[33,5065,5066],{"class":75},"  }, [data, filters, searchQuery])\n",[33,5068,5069],{"class":35,"line":3805},[33,5070,65],{"emptyLinePlaceholder":64},[33,5072,5073,5075,5078,5080,5083,5085,5087],{"class":35,"line":3814},[33,5074,900],{"class":71},[33,5076,5077],{"class":132}," hasData",[33,5079,906],{"class":71},[33,5081,5082],{"class":75}," data.",[33,5084,523],{"class":132},[33,5086,613],{"class":71},[33,5088,4273],{"class":132},[33,5090,5091,5093,5096,5098,5101,5103,5105],{"class":35,"line":3835},[33,5092,900],{"class":71},[33,5094,5095],{"class":132}," hasResults",[33,5097,906],{"class":71},[33,5099,5100],{"class":75}," filteredData.",[33,5102,523],{"class":132},[33,5104,613],{"class":71},[33,5106,4273],{"class":132},[33,5108,5109,5111,5114,5116,5118,5121,5124,5127,5129,5132,5134,5137,5139,5141,5143,5145,5147,5149],{"class":35,"line":3854},[33,5110,900],{"class":71},[33,5112,5113],{"class":132}," hasActiveFilters",[33,5115,906],{"class":71},[33,5117,4981],{"class":75},[33,5119,5120],{"class":103},"values",[33,5122,5123],{"class":75},"(filters).",[33,5125,5126],{"class":103},"some",[33,5128,915],{"class":75},[33,5130,5131],{"class":110},"v",[33,5133,921],{"class":71},[33,5135,5136],{"class":75}," v ",[33,5138,4394],{"class":71},[33,5140,731],{"class":132},[33,5142,526],{"class":71},[33,5144,5136],{"class":75},[33,5146,4394],{"class":71},[33,5148,5018],{"class":82},[33,5150,933],{"class":75},[33,5152,5153],{"class":35,"line":3873},[33,5154,65],{"emptyLinePlaceholder":64},[33,5156,5157,5159,5161,5163,5166,5168,5170,5173],{"class":35,"line":3881},[33,5158,1243],{"class":71},[33,5160,2642],{"class":75},[33,5162,2645],{"class":71},[33,5164,5165],{"class":75},"hasData) ",[33,5167,351],{"class":71},[33,5169,129],{"class":75},[33,5171,5172],{"class":132},"EmptyDataState",[33,5174,147],{"class":75},[33,5176,5177,5179,5181,5183,5186,5188,5191,5193,5195,5198,5201,5203,5205,5207,5210,5213],{"class":35,"line":3887},[33,5178,1243],{"class":71},[33,5180,2642],{"class":75},[33,5182,2645],{"class":71},[33,5184,5185],{"class":75},"hasResults ",[33,5187,224],{"class":71},[33,5189,5190],{"class":75}," hasActiveFilters) ",[33,5192,351],{"class":71},[33,5194,129],{"class":75},[33,5196,5197],{"class":132},"NoMatchesState",[33,5199,5200],{"class":103}," onClear",[33,5202,234],{"class":71},[33,5204,1540],{"class":75},[33,5206,324],{"class":71},[33,5208,5209],{"class":75}," filters.",[33,5211,5212],{"class":103},"clearAll",[33,5214,5215],{"class":75},"()} \u002F>\n",[33,5217,5218,5220,5222,5224,5227,5229,5231,5234,5236,5238],{"class":35,"line":3895},[33,5219,1243],{"class":71},[33,5221,2642],{"class":75},[33,5223,2645],{"class":71},[33,5225,5226],{"class":75},"hasResults) ",[33,5228,351],{"class":71},[33,5230,129],{"class":75},[33,5232,5233],{"class":132},"NoDataAfterSearchState",[33,5235,1469],{"class":103},[33,5237,234],{"class":71},[33,5239,5240],{"class":75},"{searchQuery} \u002F>\n",[33,5242,5243],{"class":35,"line":3904},[33,5244,65],{"emptyLinePlaceholder":64},[33,5246,5247,5249],{"class":35,"line":3909},[33,5248,120],{"class":71},[33,5250,187],{"class":75},[33,5252,5254,5256,5258],{"class":35,"line":5253},98,[33,5255,193],{"class":75},[33,5257,948],{"class":196},[33,5259,200],{"class":75},[33,5261,5263,5266,5268,5270,5272,5274,5276,5279,5281,5283,5286,5288,5290],{"class":35,"line":5262},99,[33,5264,5265],{"class":75},"      {filteredData.",[33,5267,959],{"class":103},[33,5269,915],{"class":75},[33,5271,4920],{"class":110},[33,5273,921],{"class":71},[33,5275,129],{"class":75},[33,5277,5278],{"class":132},"DataRow",[33,5280,973],{"class":103},[33,5282,234],{"class":71},[33,5284,5285],{"class":75},"{item.id} ",[33,5287,4920],{"class":103},[33,5289,234],{"class":71},[33,5291,5292],{"class":75},"{item} \u002F>)}\n",[33,5294,5296,5298,5300],{"class":35,"line":5295},100,[33,5297,251],{"class":75},[33,5299,948],{"class":196},[33,5301,200],{"class":75},[33,5303,5305],{"class":35,"line":5304},101,[33,5306,261],{"class":75},[33,5308,5310],{"class":35,"line":5309},102,[33,5311,153],{"class":75},[14,5313,5315],{"id":5314},"complex-implementation-multi-state-data-fetching-component","Complex Implementation: Multi-State Data Fetching Component",[19,5317,5319],{"filename":5318,"language":22},"data_fetch_component.js",[24,5320,5322],{"className":26,"code":5321,"language":22,"meta":28,"style":28},"import { useState, useEffect, useCallback } from 'react'\n\n\u002F\u002F A production-grade data-fetching component with all conditional states:\n\u002F\u002F idle → loading → success (populated | empty) | error → retry\n\nconst FETCH_STATES = {\n  IDLE: 'idle',\n  LOADING: 'loading',\n  SUCCESS: 'success',\n  ERROR: 'error',\n}\n\nfunction useAsyncData(fetchFn, deps = []) {\n  const [state, setState] = useState({ status: FETCH_STATES.IDLE, data: null, error: null })\n\n  const execute = useCallback(async (...args) => {\n    setState(prev => ({ ...prev, status: FETCH_STATES.LOADING, error: null }))\n    try {\n      const data = await fetchFn(...args)\n      setState({ status: FETCH_STATES.SUCCESS, data, error: null })\n      return data\n    } catch (err) {\n      setState({ status: FETCH_STATES.ERROR, data: null, error: err })\n      throw err\n    }\n  }, deps)\n\n  const reset = useCallback(() => {\n    setState({ status: FETCH_STATES.IDLE, data: null, error: null })\n  }, [])\n\n  return { ...state, execute, reset }\n}\n\nfunction DataList({ query, page }) {\n  const { status, data, error, execute, reset } = useAsyncData(\n    useCallback((q, p) => api.fetchItems({ query: q, page: p }), [])\n  )\n\n  useEffect(() => {\n    if (query) execute(query, page)\n    else reset()\n  }, [query, page, execute, reset])\n\n  \u002F\u002F ── Conditional rendering via enum + early returns ──\n  if (status === FETCH_STATES.IDLE)    return \u003CPromptState message=\"Enter a search query to begin\" \u002F>\n  if (status === FETCH_STATES.LOADING) return \u003CSkeletonGrid count={12} \u002F>\n  if (status === FETCH_STATES.ERROR)   return \u003CErrorState error={error} onRetry={() => execute(query, page)} \u002F>\n\n  \u002F\u002F status === SUCCESS here — split into populated vs empty\n  if (data.items.length === 0) {\n    return \u003CEmptyState message={`No results for \"${query}\"`} suggestion=\"Try different keywords\" \u002F>\n  }\n\n  return (\n    \u003C>\n      \u003CResultCount total={data.total} page={page} \u002F>\n      \u003Cul>\n        {data.items.map(item => (\n          \u003CDataCard key={item.id} item={item} \u002F>\n        ))}\n      \u003C\u002Ful>\n      \u003CPagination current={page} total={data.totalPages} \u002F>\n    \u003C\u002F>\n  )\n}\n",[30,5323,5324,5335,5339,5344,5349,5353,5364,5375,5385,5395,5405,5409,5413,5435,5480,5484,5514,5547,5554,5576,5597,5604,5615,5635,5643,5647,5652,5656,5673,5695,5700,5704,5715,5719,5723,5741,5777,5805,5809,5813,5823,5835,5845,5850,5854,5859,5891,5925,5966,5970,5975,5990,6023,6027,6031,6037,6042,6064,6072,6087,6107,6111,6119,6142,6147,6151],{"__ignoreMap":28},[33,5325,5326,5328,5331,5333],{"class":35,"line":36},[33,5327,72],{"class":71},[33,5329,5330],{"class":75}," { useState, useEffect, useCallback } ",[33,5332,79],{"class":71},[33,5334,83],{"class":82},[33,5336,5337],{"class":35,"line":43},[33,5338,65],{"emptyLinePlaceholder":64},[33,5340,5341],{"class":35,"line":49},[33,5342,5343],{"class":39},"\u002F\u002F A production-grade data-fetching component with all conditional states:\n",[33,5345,5346],{"class":35,"line":55},[33,5347,5348],{"class":39},"\u002F\u002F idle → loading → success (populated | empty) | error → retry\n",[33,5350,5351],{"class":35,"line":61},[33,5352,65],{"emptyLinePlaceholder":64},[33,5354,5355,5357,5360,5362],{"class":35,"line":68},[33,5356,2347],{"class":71},[33,5358,5359],{"class":132}," FETCH_STATES",[33,5361,906],{"class":71},[33,5363,327],{"class":75},[33,5365,5366,5369,5372],{"class":35,"line":86},[33,5367,5368],{"class":75},"  IDLE: ",[33,5370,5371],{"class":82},"'idle'",[33,5373,5374],{"class":75},",\n",[33,5376,5377,5380,5383],{"class":35,"line":91},[33,5378,5379],{"class":75},"  LOADING: ",[33,5381,5382],{"class":82},"'loading'",[33,5384,5374],{"class":75},[33,5386,5387,5390,5393],{"class":35,"line":97},[33,5388,5389],{"class":75},"  SUCCESS: ",[33,5391,5392],{"class":82},"'success'",[33,5394,5374],{"class":75},[33,5396,5397,5400,5403],{"class":35,"line":117},[33,5398,5399],{"class":75},"  ERROR: ",[33,5401,5402],{"class":82},"'error'",[33,5404,5374],{"class":75},[33,5406,5407],{"class":35,"line":150},[33,5408,153],{"class":75},[33,5410,5411],{"class":35,"line":156},[33,5412,65],{"emptyLinePlaceholder":64},[33,5414,5415,5417,5420,5422,5425,5427,5430,5432],{"class":35,"line":161},[33,5416,100],{"class":71},[33,5418,5419],{"class":103}," useAsyncData",[33,5421,915],{"class":75},[33,5423,5424],{"class":110},"fetchFn",[33,5426,293],{"class":75},[33,5428,5429],{"class":110},"deps",[33,5431,906],{"class":71},[33,5433,5434],{"class":75}," []) {\n",[33,5436,5437,5439,5441,5444,5446,5449,5451,5453,5455,5458,5461,5463,5466,5469,5472,5475,5477],{"class":35,"line":167},[33,5438,900],{"class":71},[33,5440,1376],{"class":75},[33,5442,5443],{"class":132},"state",[33,5445,293],{"class":75},[33,5447,5448],{"class":132},"setState",[33,5450,1387],{"class":75},[33,5452,234],{"class":71},[33,5454,1392],{"class":103},[33,5456,5457],{"class":75},"({ status: ",[33,5459,5460],{"class":132},"FETCH_STATES",[33,5462,2675],{"class":75},[33,5464,5465],{"class":132},"IDLE",[33,5467,5468],{"class":75},", data: ",[33,5470,5471],{"class":132},"null",[33,5473,5474],{"class":75},", error: ",[33,5476,5471],{"class":132},[33,5478,5479],{"class":75}," })\n",[33,5481,5482],{"class":35,"line":182},[33,5483,65],{"emptyLinePlaceholder":64},[33,5485,5486,5488,5491,5493,5496,5498,5501,5503,5505,5508,5510,5512],{"class":35,"line":190},[33,5487,900],{"class":71},[33,5489,5490],{"class":132}," execute",[33,5492,906],{"class":71},[33,5494,5495],{"class":103}," useCallback",[33,5497,915],{"class":75},[33,5499,5500],{"class":71},"async",[33,5502,2642],{"class":75},[33,5504,2616],{"class":71},[33,5506,5507],{"class":110},"args",[33,5509,1253],{"class":75},[33,5511,324],{"class":71},[33,5513,327],{"class":75},[33,5515,5516,5519,5521,5523,5525,5528,5530,5533,5535,5537,5540,5542,5544],{"class":35,"line":203},[33,5517,5518],{"class":103},"    setState",[33,5520,915],{"class":75},[33,5522,3558],{"class":110},[33,5524,921],{"class":71},[33,5526,5527],{"class":75}," ({ ",[33,5529,2616],{"class":71},[33,5531,5532],{"class":75},"prev, status: ",[33,5534,5460],{"class":132},[33,5536,2675],{"class":75},[33,5538,5539],{"class":132},"LOADING",[33,5541,5474],{"class":75},[33,5543,5471],{"class":132},[33,5545,5546],{"class":75}," }))\n",[33,5548,5549,5552],{"class":35,"line":218},[33,5550,5551],{"class":71},"    try",[33,5553,327],{"class":75},[33,5555,5556,5559,5561,5563,5566,5569,5571,5573],{"class":35,"line":248},[33,5557,5558],{"class":71},"      const",[33,5560,1701],{"class":132},[33,5562,906],{"class":71},[33,5564,5565],{"class":71}," await",[33,5567,5568],{"class":103}," fetchFn",[33,5570,915],{"class":75},[33,5572,2616],{"class":71},[33,5574,5575],{"class":75},"args)\n",[33,5577,5578,5581,5583,5585,5587,5590,5593,5595],{"class":35,"line":258},[33,5579,5580],{"class":103},"      setState",[33,5582,5457],{"class":75},[33,5584,5460],{"class":132},[33,5586,2675],{"class":75},[33,5588,5589],{"class":132},"SUCCESS",[33,5591,5592],{"class":75},", data, error: ",[33,5594,5471],{"class":132},[33,5596,5479],{"class":75},[33,5598,5599,5602],{"class":35,"line":264},[33,5600,5601],{"class":71},"      return",[33,5603,4896],{"class":75},[33,5605,5606,5609,5612],{"class":35,"line":269},[33,5607,5608],{"class":75},"    } ",[33,5610,5611],{"class":71},"catch",[33,5613,5614],{"class":75}," (err) {\n",[33,5616,5617,5619,5621,5623,5625,5628,5630,5632],{"class":35,"line":274},[33,5618,5580],{"class":103},[33,5620,5457],{"class":75},[33,5622,5460],{"class":132},[33,5624,2675],{"class":75},[33,5626,5627],{"class":132},"ERROR",[33,5629,5468],{"class":75},[33,5631,5471],{"class":132},[33,5633,5634],{"class":75},", error: err })\n",[33,5636,5637,5640],{"class":35,"line":280},[33,5638,5639],{"class":71},"      throw",[33,5641,5642],{"class":75}," err\n",[33,5644,5645],{"class":35,"line":301},[33,5646,4954],{"class":75},[33,5648,5649],{"class":35,"line":308},[33,5650,5651],{"class":75},"  }, deps)\n",[33,5653,5654],{"class":35,"line":318},[33,5655,65],{"emptyLinePlaceholder":64},[33,5657,5658,5660,5663,5665,5667,5669,5671],{"class":35,"line":330},[33,5659,900],{"class":71},[33,5661,5662],{"class":132}," reset",[33,5664,906],{"class":71},[33,5666,5495],{"class":103},[33,5668,1411],{"class":75},[33,5670,324],{"class":71},[33,5672,327],{"class":75},[33,5674,5675,5677,5679,5681,5683,5685,5687,5689,5691,5693],{"class":35,"line":339},[33,5676,5518],{"class":103},[33,5678,5457],{"class":75},[33,5680,5460],{"class":132},[33,5682,2675],{"class":75},[33,5684,5465],{"class":132},[33,5686,5468],{"class":75},[33,5688,5471],{"class":132},[33,5690,5474],{"class":75},[33,5692,5471],{"class":132},[33,5694,5479],{"class":75},[33,5696,5697],{"class":35,"line":367},[33,5698,5699],{"class":75},"  }, [])\n",[33,5701,5702],{"class":35,"line":392},[33,5703,65],{"emptyLinePlaceholder":64},[33,5705,5706,5708,5710,5712],{"class":35,"line":412},[33,5707,120],{"class":71},[33,5709,1545],{"class":75},[33,5711,2616],{"class":71},[33,5713,5714],{"class":75},"state, execute, reset }\n",[33,5716,5717],{"class":35,"line":430},[33,5718,153],{"class":75},[33,5720,5721],{"class":35,"line":436},[33,5722,65],{"emptyLinePlaceholder":64},[33,5724,5725,5727,5730,5732,5734,5736,5739],{"class":35,"line":442},[33,5726,100],{"class":71},[33,5728,5729],{"class":103}," DataList",[33,5731,107],{"class":75},[33,5733,1357],{"class":110},[33,5735,293],{"class":75},[33,5737,5738],{"class":110},"page",[33,5740,114],{"class":75},[33,5742,5743,5745,5747,5749,5751,5753,5755,5757,5759,5762,5764,5767,5770,5772,5774],{"class":35,"line":451},[33,5744,900],{"class":71},[33,5746,1545],{"class":75},[33,5748,1088],{"class":132},[33,5750,293],{"class":75},[33,5752,296],{"class":132},[33,5754,293],{"class":75},[33,5756,1098],{"class":132},[33,5758,293],{"class":75},[33,5760,5761],{"class":132},"execute",[33,5763,293],{"class":75},[33,5765,5766],{"class":132},"reset",[33,5768,5769],{"class":75}," } ",[33,5771,234],{"class":71},[33,5773,5419],{"class":103},[33,5775,5776],{"class":75},"(\n",[33,5778,5779,5782,5784,5787,5789,5792,5794,5796,5799,5802],{"class":35,"line":456},[33,5780,5781],{"class":103},"    useCallback",[33,5783,4428],{"class":75},[33,5785,5786],{"class":110},"q",[33,5788,293],{"class":75},[33,5790,5791],{"class":110},"p",[33,5793,1253],{"class":75},[33,5795,324],{"class":71},[33,5797,5798],{"class":75}," api.",[33,5800,5801],{"class":103},"fetchItems",[33,5803,5804],{"class":75},"({ query: q, page: p }), [])\n",[33,5806,5807],{"class":35,"line":462},[33,5808,261],{"class":75},[33,5810,5811],{"class":35,"line":468},[33,5812,65],{"emptyLinePlaceholder":64},[33,5814,5815,5817,5819,5821],{"class":35,"line":826},[33,5816,1408],{"class":103},[33,5818,1411],{"class":75},[33,5820,324],{"class":71},[33,5822,327],{"class":75},[33,5824,5825,5827,5830,5832],{"class":35,"line":847},[33,5826,1420],{"class":71},[33,5828,5829],{"class":75}," (query) ",[33,5831,5761],{"class":103},[33,5833,5834],{"class":75},"(query, page)\n",[33,5836,5837,5840,5842],{"class":35,"line":853},[33,5838,5839],{"class":71},"    else",[33,5841,5662],{"class":103},[33,5843,5844],{"class":75},"()\n",[33,5846,5847],{"class":35,"line":862},[33,5848,5849],{"class":75},"  }, [query, page, execute, reset])\n",[33,5851,5852],{"class":35,"line":867},[33,5853,65],{"emptyLinePlaceholder":64},[33,5855,5856],{"class":35,"line":872},[33,5857,5858],{"class":39},"  \u002F\u002F ── Conditional rendering via enum + early returns ──\n",[33,5860,5861,5863,5865,5867,5869,5871,5873,5875,5877,5879,5882,5884,5886,5889],{"class":35,"line":877},[33,5862,1243],{"class":71},[33,5864,1246],{"class":75},[33,5866,1110],{"class":71},[33,5868,5359],{"class":132},[33,5870,2675],{"class":75},[33,5872,5465],{"class":132},[33,5874,1459],{"class":75},[33,5876,351],{"class":71},[33,5878,129],{"class":75},[33,5880,5881],{"class":132},"PromptState",[33,5883,1615],{"class":103},[33,5885,234],{"class":71},[33,5887,5888],{"class":82},"\"Enter a search query to begin\"",[33,5890,147],{"class":75},[33,5892,5893,5895,5897,5899,5901,5903,5905,5907,5909,5911,5914,5916,5918,5920,5923],{"class":35,"line":883},[33,5894,1243],{"class":71},[33,5896,1246],{"class":75},[33,5898,1110],{"class":71},[33,5900,5359],{"class":132},[33,5902,2675],{"class":75},[33,5904,5539],{"class":132},[33,5906,1253],{"class":75},[33,5908,351],{"class":71},[33,5910,129],{"class":75},[33,5912,5913],{"class":132},"SkeletonGrid",[33,5915,1496],{"class":103},[33,5917,234],{"class":71},[33,5919,1501],{"class":75},[33,5921,5922],{"class":132},"12",[33,5924,1507],{"class":75},[33,5926,5927,5929,5931,5933,5935,5937,5939,5941,5943,5945,5947,5949,5951,5953,5955,5957,5959,5961,5963],{"class":35,"line":897},[33,5928,1243],{"class":71},[33,5930,1246],{"class":75},[33,5932,1110],{"class":71},[33,5934,5359],{"class":132},[33,5936,2675],{"class":75},[33,5938,5627],{"class":132},[33,5940,1274],{"class":75},[33,5942,351],{"class":71},[33,5944,129],{"class":75},[33,5946,1526],{"class":132},[33,5948,1154],{"class":103},[33,5950,234],{"class":71},[33,5952,1533],{"class":75},[33,5954,1362],{"class":103},[33,5956,234],{"class":71},[33,5958,1540],{"class":75},[33,5960,324],{"class":71},[33,5962,5490],{"class":103},[33,5964,5965],{"class":75},"(query, page)} \u002F>\n",[33,5967,5968],{"class":35,"line":936},[33,5969,65],{"emptyLinePlaceholder":64},[33,5971,5972],{"class":35,"line":943},[33,5973,5974],{"class":39},"  \u002F\u002F status === SUCCESS here — split into populated vs empty\n",[33,5976,5977,5979,5982,5984,5986,5988],{"class":35,"line":953},[33,5978,1243],{"class":71},[33,5980,5981],{"class":75}," (data.items.",[33,5983,523],{"class":132},[33,5985,993],{"class":71},[33,5987,616],{"class":132},[33,5989,1602],{"class":75},[33,5991,5992,5994,5996,5998,6000,6002,6004,6006,6008,6010,6013,6016,6018,6021],{"class":35,"line":986},[33,5993,1607],{"class":71},[33,5995,129],{"class":75},[33,5997,1612],{"class":132},[33,5999,1615],{"class":103},[33,6001,234],{"class":71},[33,6003,1501],{"class":75},[33,6005,1622],{"class":82},[33,6007,1357],{"class":75},[33,6009,1627],{"class":82},[33,6011,6012],{"class":75},"} ",[33,6014,6015],{"class":103},"suggestion",[33,6017,234],{"class":71},[33,6019,6020],{"class":82},"\"Try different keywords\"",[33,6022,147],{"class":75},[33,6024,6025],{"class":35,"line":1011},[33,6026,1634],{"class":75},[33,6028,6029],{"class":35,"line":1022},[33,6030,65],{"emptyLinePlaceholder":64},[33,6032,6033,6035],{"class":35,"line":1028},[33,6034,120],{"class":71},[33,6036,187],{"class":75},[33,6038,6039],{"class":35,"line":1037},[33,6040,6041],{"class":75},"    \u003C>\n",[33,6043,6044,6046,6049,6052,6054,6057,6059,6061],{"class":35,"line":1042},[33,6045,206],{"class":75},[33,6047,6048],{"class":132},"ResultCount",[33,6050,6051],{"class":103}," total",[33,6053,234],{"class":71},[33,6055,6056],{"class":75},"{data.total} ",[33,6058,5738],{"class":103},[33,6060,234],{"class":71},[33,6062,6063],{"class":75},"{page} \u002F>\n",[33,6065,6066,6068,6070],{"class":35,"line":2861},[33,6067,206],{"class":75},[33,6069,948],{"class":196},[33,6071,200],{"class":75},[33,6073,6074,6077,6079,6081,6083,6085],{"class":35,"line":2866},[33,6075,6076],{"class":75},"        {data.items.",[33,6078,959],{"class":103},[33,6080,915],{"class":75},[33,6082,4920],{"class":110},[33,6084,921],{"class":71},[33,6086,187],{"class":75},[33,6088,6089,6091,6094,6096,6098,6100,6102,6104],{"class":35,"line":2871},[33,6090,1681],{"class":75},[33,6092,6093],{"class":132},"DataCard",[33,6095,973],{"class":103},[33,6097,234],{"class":71},[33,6099,5285],{"class":75},[33,6101,4920],{"class":103},[33,6103,234],{"class":71},[33,6105,6106],{"class":75},"{item} \u002F>\n",[33,6108,6109],{"class":35,"line":2890},[33,6110,1720],{"class":75},[33,6112,6113,6115,6117],{"class":35,"line":2912},[33,6114,1725],{"class":75},[33,6116,948],{"class":196},[33,6118,200],{"class":75},[33,6120,6121,6123,6126,6129,6131,6134,6137,6139],{"class":35,"line":2922},[33,6122,206],{"class":75},[33,6124,6125],{"class":132},"Pagination",[33,6127,6128],{"class":103}," current",[33,6130,234],{"class":71},[33,6132,6133],{"class":75},"{page} ",[33,6135,6136],{"class":103},"total",[33,6138,234],{"class":71},[33,6140,6141],{"class":75},"{data.totalPages} \u002F>\n",[33,6143,6144],{"class":35,"line":3539},[33,6145,6146],{"class":75},"    \u003C\u002F>\n",[33,6148,6149],{"class":35,"line":3550},[33,6150,261],{"class":75},[33,6152,6153],{"class":35,"line":3575},[33,6154,153],{"class":75},[14,6156,6158],{"id":6157},"render-props-legacy-but-still-useful","Render Props (Legacy but Still Useful)",[19,6160,6162],{"filename":6161,"language":22},"render_props.js",[24,6163,6165],{"className":26,"code":6164,"language":22,"meta":28,"style":28},"import { useState, useEffect } from 'react'\n\n\u002F\u002F Render prop: a prop whose value is a function returning JSX.\n\u002F\u002F Useful when a component controls WHEN\u002FWHAT data is available but the consumer\n\u002F\u002F controls HOW to render it. Predates hooks; still valid for rendering delegation.\n\nfunction MouseTracker({ children }) {\n  const [pos, setPos] = useState({ x: 0, y: 0 })\n\n  useEffect(() => {\n    const handler = (e) => setPos({ x: e.clientX, y: e.clientY })\n    window.addEventListener('mousemove', handler)\n    return () => window.removeEventListener('mousemove', handler)\n  }, [])\n\n  return children(pos)  \u002F\u002F children is a FUNCTION, not JSX\n}\n\n\u002F\u002F Usage:\n\u003CMouseTracker>\n  {({ x, y }) => \u003Cp>Mouse at ({x}, {y})\u003C\u002Fp>}\n\u003C\u002FMouseTracker>\n\n\u002F\u002F ANTI-PATTERN: using render prop for pure logic reuse when a custom hook is simpler\n\u002F\u002F Render props add a component nesting level and re-create the function every render.\n\u002F\u002F For LOGIC reuse (not rendering delegation), use a custom hook:\nfunction useMousePosition() {\n  const [pos, setPos] = useState({ x: 0, y: 0 })\n  useEffect(() => {\n    const handler = (e) => setPos({ x: e.clientX, y: e.clientY })\n    window.addEventListener('mousemove', handler)\n    return () => window.removeEventListener('mousemove', handler)\n  }, [])\n  return pos\n}\n\u002F\u002F Usage: const { x, y } = useMousePosition() — no wrapper component, no extra nesting.\n",[30,6166,6167,6177,6181,6186,6191,6196,6200,6214,6246,6250,6260,6285,6301,6322,6326,6330,6343,6347,6351,6356,6365,6393,6402,6406,6411,6416,6421,6430,6458,6468,6488,6500,6518,6522,6529,6533],{"__ignoreMap":28},[33,6168,6169,6171,6173,6175],{"class":35,"line":36},[33,6170,72],{"class":71},[33,6172,1063],{"class":75},[33,6174,79],{"class":71},[33,6176,83],{"class":82},[33,6178,6179],{"class":35,"line":43},[33,6180,65],{"emptyLinePlaceholder":64},[33,6182,6183],{"class":35,"line":49},[33,6184,6185],{"class":39},"\u002F\u002F Render prop: a prop whose value is a function returning JSX.\n",[33,6187,6188],{"class":35,"line":55},[33,6189,6190],{"class":39},"\u002F\u002F Useful when a component controls WHEN\u002FWHAT data is available but the consumer\n",[33,6192,6193],{"class":35,"line":61},[33,6194,6195],{"class":39},"\u002F\u002F controls HOW to render it. Predates hooks; still valid for rendering delegation.\n",[33,6197,6198],{"class":35,"line":68},[33,6199,65],{"emptyLinePlaceholder":64},[33,6201,6202,6204,6207,6209,6212],{"class":35,"line":86},[33,6203,100],{"class":71},[33,6205,6206],{"class":103}," MouseTracker",[33,6208,107],{"class":75},[33,6210,6211],{"class":110},"children",[33,6213,114],{"class":75},[33,6215,6216,6218,6220,6223,6225,6228,6230,6232,6234,6237,6239,6242,6244],{"class":35,"line":91},[33,6217,900],{"class":71},[33,6219,1376],{"class":75},[33,6221,6222],{"class":132},"pos",[33,6224,293],{"class":75},[33,6226,6227],{"class":132},"setPos",[33,6229,1387],{"class":75},[33,6231,234],{"class":71},[33,6233,1392],{"class":103},[33,6235,6236],{"class":75},"({ x: ",[33,6238,1397],{"class":132},[33,6240,6241],{"class":75},", y: ",[33,6243,1397],{"class":132},[33,6245,5479],{"class":75},[33,6247,6248],{"class":35,"line":97},[33,6249,65],{"emptyLinePlaceholder":64},[33,6251,6252,6254,6256,6258],{"class":35,"line":117},[33,6253,1408],{"class":103},[33,6255,1411],{"class":75},[33,6257,324],{"class":71},[33,6259,327],{"class":75},[33,6261,6262,6265,6268,6270,6272,6275,6277,6279,6282],{"class":35,"line":150},[33,6263,6264],{"class":71},"    const",[33,6266,6267],{"class":103}," handler",[33,6269,906],{"class":71},[33,6271,2642],{"class":75},[33,6273,6274],{"class":110},"e",[33,6276,1253],{"class":75},[33,6278,324],{"class":71},[33,6280,6281],{"class":103}," setPos",[33,6283,6284],{"class":75},"({ x: e.clientX, y: e.clientY })\n",[33,6286,6287,6290,6293,6295,6298],{"class":35,"line":156},[33,6288,6289],{"class":75},"    window.",[33,6291,6292],{"class":103},"addEventListener",[33,6294,915],{"class":75},[33,6296,6297],{"class":82},"'mousemove'",[33,6299,6300],{"class":75},", handler)\n",[33,6302,6303,6305,6308,6310,6313,6316,6318,6320],{"class":35,"line":161},[33,6304,1607],{"class":71},[33,6306,6307],{"class":75}," () ",[33,6309,324],{"class":71},[33,6311,6312],{"class":75}," window.",[33,6314,6315],{"class":103},"removeEventListener",[33,6317,915],{"class":75},[33,6319,6297],{"class":82},[33,6321,6300],{"class":75},[33,6323,6324],{"class":35,"line":167},[33,6325,5699],{"class":75},[33,6327,6328],{"class":35,"line":182},[33,6329,65],{"emptyLinePlaceholder":64},[33,6331,6332,6334,6337,6340],{"class":35,"line":190},[33,6333,120],{"class":71},[33,6335,6336],{"class":103}," children",[33,6338,6339],{"class":75},"(pos)  ",[33,6341,6342],{"class":39},"\u002F\u002F children is a FUNCTION, not JSX\n",[33,6344,6345],{"class":35,"line":203},[33,6346,153],{"class":75},[33,6348,6349],{"class":35,"line":218},[33,6350,65],{"emptyLinePlaceholder":64},[33,6352,6353],{"class":35,"line":248},[33,6354,6355],{"class":39},"\u002F\u002F Usage:\n",[33,6357,6358,6360,6363],{"class":35,"line":258},[33,6359,1804],{"class":75},[33,6361,6362],{"class":132},"MouseTracker",[33,6364,200],{"class":75},[33,6366,6367,6370,6372,6374,6377,6380,6382,6384,6386,6389,6391],{"class":35,"line":264},[33,6368,6369],{"class":75},"  {({ ",[33,6371,918],{"class":110},[33,6373,293],{"class":75},[33,6375,6376],{"class":110},"y",[33,6378,6379],{"class":75}," }) ",[33,6381,324],{"class":71},[33,6383,129],{"class":75},[33,6385,5791],{"class":196},[33,6387,6388],{"class":75},">Mouse at ({x}, {y})\u003C\u002F",[33,6390,5791],{"class":196},[33,6392,245],{"class":75},[33,6394,6395,6398,6400],{"class":35,"line":269},[33,6396,6397],{"class":75},"\u003C\u002F",[33,6399,6362],{"class":132},[33,6401,200],{"class":75},[33,6403,6404],{"class":35,"line":274},[33,6405,65],{"emptyLinePlaceholder":64},[33,6407,6408],{"class":35,"line":280},[33,6409,6410],{"class":39},"\u002F\u002F ANTI-PATTERN: using render prop for pure logic reuse when a custom hook is simpler\n",[33,6412,6413],{"class":35,"line":301},[33,6414,6415],{"class":39},"\u002F\u002F Render props add a component nesting level and re-create the function every render.\n",[33,6417,6418],{"class":35,"line":308},[33,6419,6420],{"class":39},"\u002F\u002F For LOGIC reuse (not rendering delegation), use a custom hook:\n",[33,6422,6423,6425,6428],{"class":35,"line":318},[33,6424,100],{"class":71},[33,6426,6427],{"class":103}," useMousePosition",[33,6429,4498],{"class":75},[33,6431,6432,6434,6436,6438,6440,6442,6444,6446,6448,6450,6452,6454,6456],{"class":35,"line":330},[33,6433,900],{"class":71},[33,6435,1376],{"class":75},[33,6437,6222],{"class":132},[33,6439,293],{"class":75},[33,6441,6227],{"class":132},[33,6443,1387],{"class":75},[33,6445,234],{"class":71},[33,6447,1392],{"class":103},[33,6449,6236],{"class":75},[33,6451,1397],{"class":132},[33,6453,6241],{"class":75},[33,6455,1397],{"class":132},[33,6457,5479],{"class":75},[33,6459,6460,6462,6464,6466],{"class":35,"line":339},[33,6461,1408],{"class":103},[33,6463,1411],{"class":75},[33,6465,324],{"class":71},[33,6467,327],{"class":75},[33,6469,6470,6472,6474,6476,6478,6480,6482,6484,6486],{"class":35,"line":367},[33,6471,6264],{"class":71},[33,6473,6267],{"class":103},[33,6475,906],{"class":71},[33,6477,2642],{"class":75},[33,6479,6274],{"class":110},[33,6481,1253],{"class":75},[33,6483,324],{"class":71},[33,6485,6281],{"class":103},[33,6487,6284],{"class":75},[33,6489,6490,6492,6494,6496,6498],{"class":35,"line":392},[33,6491,6289],{"class":75},[33,6493,6292],{"class":103},[33,6495,915],{"class":75},[33,6497,6297],{"class":82},[33,6499,6300],{"class":75},[33,6501,6502,6504,6506,6508,6510,6512,6514,6516],{"class":35,"line":412},[33,6503,1607],{"class":71},[33,6505,6307],{"class":75},[33,6507,324],{"class":71},[33,6509,6312],{"class":75},[33,6511,6315],{"class":103},[33,6513,915],{"class":75},[33,6515,6297],{"class":82},[33,6517,6300],{"class":75},[33,6519,6520],{"class":35,"line":430},[33,6521,5699],{"class":75},[33,6523,6524,6526],{"class":35,"line":436},[33,6525,120],{"class":71},[33,6527,6528],{"class":75}," pos\n",[33,6530,6531],{"class":35,"line":442},[33,6532,153],{"class":75},[33,6534,6535],{"class":35,"line":451},[33,6536,6537],{"class":39},"\u002F\u002F Usage: const { x, y } = useMousePosition() — no wrapper component, no extra nesting.\n",[14,6539,6541],{"id":6540},"tips-tricks","💡 Tips & Tricks",[19,6543,6545],{"filename":6544,"language":22},"tips.js",[24,6546,6548],{"className":26,"code":6547,"language":22,"meta":28,"style":28},"\u002F\u002F [Idiom] Use ternary for exactly 2 branches, && for \"render or nothing\",\n\u002F\u002F early returns for 3+ whole-component branches, enum objects for N-value lookups.\n\n\u002F\u002F [Performance] Show\u002Fhide (CSS display:none) preserves state and avoids remount cost\n\u002F\u002F for heavy components (charts, editors). Mount\u002Funmount saves DOM weight but loses state.\n\u002F\u002F Use the hybrid \"keep visited mounted\" pattern for tabbed UIs with expensive panels.\n\n\u002F\u002F [Debug] \"Rendered fewer hooks than expected\" = a hook is after an early return.\n\u002F\u002F Move ALL hooks above ALL conditional returns. Hook count must be constant per render.\n\n\u002F\u002F [Idiom] Extract complex inline conditionals to named boolean variables:\n\u002F\u002F   const canEdit = user && user.role === 'admin' && !isLocked\n\u002F\u002F   {canEdit && \u003CEditButton \u002F>}\n\u002F\u002F Self-documenting, testable, and the JSX stays clean.\n\n\u002F\u002F [Safety] Always provide a fallback for enum lookups:\n\u002F\u002F   STATUS_CONFIG[status] ?? \u003CFallback \u002F>  or  STATUS_CONFIG[status] || defaultConfig\n\u002F\u002F Without it, an unexpected status renders undefined (nothing) silently.\n\n\u002F\u002F [Idiom] For component registries, throw with a diagnostic message on unknown keys:\n\u002F\u002F   if (!Component) throw new Error(`Unknown step: \"${step}\". Valid: ${keys}`)\n\u002F\u002F This surfaces typos immediately instead of the cryptic \"Element type is invalid\".\n",[30,6549,6550,6555,6560,6564,6569,6574,6579,6583,6588,6593,6597,6602,6607,6612,6617,6621,6626,6631,6636,6640,6645,6650],{"__ignoreMap":28},[33,6551,6552],{"class":35,"line":36},[33,6553,6554],{"class":39},"\u002F\u002F [Idiom] Use ternary for exactly 2 branches, && for \"render or nothing\",\n",[33,6556,6557],{"class":35,"line":43},[33,6558,6559],{"class":39},"\u002F\u002F early returns for 3+ whole-component branches, enum objects for N-value lookups.\n",[33,6561,6562],{"class":35,"line":49},[33,6563,65],{"emptyLinePlaceholder":64},[33,6565,6566],{"class":35,"line":55},[33,6567,6568],{"class":39},"\u002F\u002F [Performance] Show\u002Fhide (CSS display:none) preserves state and avoids remount cost\n",[33,6570,6571],{"class":35,"line":61},[33,6572,6573],{"class":39},"\u002F\u002F for heavy components (charts, editors). Mount\u002Funmount saves DOM weight but loses state.\n",[33,6575,6576],{"class":35,"line":68},[33,6577,6578],{"class":39},"\u002F\u002F Use the hybrid \"keep visited mounted\" pattern for tabbed UIs with expensive panels.\n",[33,6580,6581],{"class":35,"line":86},[33,6582,65],{"emptyLinePlaceholder":64},[33,6584,6585],{"class":35,"line":91},[33,6586,6587],{"class":39},"\u002F\u002F [Debug] \"Rendered fewer hooks than expected\" = a hook is after an early return.\n",[33,6589,6590],{"class":35,"line":97},[33,6591,6592],{"class":39},"\u002F\u002F Move ALL hooks above ALL conditional returns. Hook count must be constant per render.\n",[33,6594,6595],{"class":35,"line":117},[33,6596,65],{"emptyLinePlaceholder":64},[33,6598,6599],{"class":35,"line":150},[33,6600,6601],{"class":39},"\u002F\u002F [Idiom] Extract complex inline conditionals to named boolean variables:\n",[33,6603,6604],{"class":35,"line":156},[33,6605,6606],{"class":39},"\u002F\u002F   const canEdit = user && user.role === 'admin' && !isLocked\n",[33,6608,6609],{"class":35,"line":161},[33,6610,6611],{"class":39},"\u002F\u002F   {canEdit && \u003CEditButton \u002F>}\n",[33,6613,6614],{"class":35,"line":167},[33,6615,6616],{"class":39},"\u002F\u002F Self-documenting, testable, and the JSX stays clean.\n",[33,6618,6619],{"class":35,"line":182},[33,6620,65],{"emptyLinePlaceholder":64},[33,6622,6623],{"class":35,"line":190},[33,6624,6625],{"class":39},"\u002F\u002F [Safety] Always provide a fallback for enum lookups:\n",[33,6627,6628],{"class":35,"line":203},[33,6629,6630],{"class":39},"\u002F\u002F   STATUS_CONFIG[status] ?? \u003CFallback \u002F>  or  STATUS_CONFIG[status] || defaultConfig\n",[33,6632,6633],{"class":35,"line":218},[33,6634,6635],{"class":39},"\u002F\u002F Without it, an unexpected status renders undefined (nothing) silently.\n",[33,6637,6638],{"class":35,"line":248},[33,6639,65],{"emptyLinePlaceholder":64},[33,6641,6642],{"class":35,"line":258},[33,6643,6644],{"class":39},"\u002F\u002F [Idiom] For component registries, throw with a diagnostic message on unknown keys:\n",[33,6646,6647],{"class":35,"line":264},[33,6648,6649],{"class":39},"\u002F\u002F   if (!Component) throw new Error(`Unknown step: \"${step}\". Valid: ${keys}`)\n",[33,6651,6652],{"class":35,"line":269},[33,6653,6654],{"class":39},"\u002F\u002F This surfaces typos immediately instead of the cryptic \"Element type is invalid\".\n",[14,6656,6658],{"id":6657},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[19,6660,6662],{"filename":6661,"language":22},"edge_cases.js",[24,6663,6665],{"className":26,"code":6664,"language":22,"meta":28,"style":28},"\u002F\u002F [Gotcha] {count && \u003CBadge \u002F>} renders \"0\" when count is 0.\n\u002F\u002F Zero is a number — React renders it. Use {count > 0 && \u003CBadge \u002F>} or a ternary.\n\n\u002F\u002F [Gotcha] Mixing && and || for branching: {cond && \u003CA \u002F> || \u003CB \u002F>}\n\u002F\u002F If \u003CA \u002F> returns null\u002F0\u002Ffalse, the || fallback fires even when cond was true.\n\u002F\u002F Use a ternary: {cond ? \u003CA \u002F> : \u003CB \u002F>}\n\n\u002F\u002F [Gotcha] Hooks after early returns don't just warn — they corrupt hook state.\n\u002F\u002F React tracks hooks by call order. If a hook is skipped, every subsequent hook\n\u002F\u002F shifts position, reading the wrong state slot. The \"fewer hooks\" error is React\n\u002F\u002F protecting you, but the corruption already happened for that render.\n\n\u002F\u002F [Gotcha] Enum lookup with no fallback renders undefined (nothing) — no error, no warning.\n\u002F\u002F STATUS_ICONS['unknown_status'] → undefined → React renders nothing → silent UI gap.\n\n\u002F\u002F [Gotcha] Component registry typo: STEP_COMPONENTS['acount'] (typo) → undefined.\n\u002F\u002F Rendering \u003Cundefined \u002F> throws \"Element type is invalid: expected a string or\n\u002F\u002F a component but got: undefined.\" — one of React's most cryptic errors.\n\n\u002F\u002F [Gotcha] CSS display:none panels still run effects (useEffect, subscriptions, polling).\n\u002F\u002F If a hidden panel sets up an interval or WebSocket, it keeps running invisibly.\n\u002F\u002F Use a \"visible\" prop and guard effects: useEffect(() => { if (!visible) return; ... })\n\n\u002F\u002F [Gotcha] show\u002Fhide with display:none does not prevent the component from being\n\u002F\u002F in the accessibility tree. Use aria-hidden=\"true\" on hidden panels, or consider\n\u002F\u002F conditional rendering for screen-reader-only content.\n",[30,6666,6667,6672,6677,6681,6686,6691,6696,6700,6705,6710,6715,6720,6724,6729,6734,6738,6743,6748,6753,6757,6762,6767,6772,6776,6781,6786],{"__ignoreMap":28},[33,6668,6669],{"class":35,"line":36},[33,6670,6671],{"class":39},"\u002F\u002F [Gotcha] {count && \u003CBadge \u002F>} renders \"0\" when count is 0.\n",[33,6673,6674],{"class":35,"line":43},[33,6675,6676],{"class":39},"\u002F\u002F Zero is a number — React renders it. Use {count > 0 && \u003CBadge \u002F>} or a ternary.\n",[33,6678,6679],{"class":35,"line":49},[33,6680,65],{"emptyLinePlaceholder":64},[33,6682,6683],{"class":35,"line":55},[33,6684,6685],{"class":39},"\u002F\u002F [Gotcha] Mixing && and || for branching: {cond && \u003CA \u002F> || \u003CB \u002F>}\n",[33,6687,6688],{"class":35,"line":61},[33,6689,6690],{"class":39},"\u002F\u002F If \u003CA \u002F> returns null\u002F0\u002Ffalse, the || fallback fires even when cond was true.\n",[33,6692,6693],{"class":35,"line":68},[33,6694,6695],{"class":39},"\u002F\u002F Use a ternary: {cond ? \u003CA \u002F> : \u003CB \u002F>}\n",[33,6697,6698],{"class":35,"line":86},[33,6699,65],{"emptyLinePlaceholder":64},[33,6701,6702],{"class":35,"line":91},[33,6703,6704],{"class":39},"\u002F\u002F [Gotcha] Hooks after early returns don't just warn — they corrupt hook state.\n",[33,6706,6707],{"class":35,"line":97},[33,6708,6709],{"class":39},"\u002F\u002F React tracks hooks by call order. If a hook is skipped, every subsequent hook\n",[33,6711,6712],{"class":35,"line":117},[33,6713,6714],{"class":39},"\u002F\u002F shifts position, reading the wrong state slot. The \"fewer hooks\" error is React\n",[33,6716,6717],{"class":35,"line":150},[33,6718,6719],{"class":39},"\u002F\u002F protecting you, but the corruption already happened for that render.\n",[33,6721,6722],{"class":35,"line":156},[33,6723,65],{"emptyLinePlaceholder":64},[33,6725,6726],{"class":35,"line":161},[33,6727,6728],{"class":39},"\u002F\u002F [Gotcha] Enum lookup with no fallback renders undefined (nothing) — no error, no warning.\n",[33,6730,6731],{"class":35,"line":167},[33,6732,6733],{"class":39},"\u002F\u002F STATUS_ICONS['unknown_status'] → undefined → React renders nothing → silent UI gap.\n",[33,6735,6736],{"class":35,"line":182},[33,6737,65],{"emptyLinePlaceholder":64},[33,6739,6740],{"class":35,"line":190},[33,6741,6742],{"class":39},"\u002F\u002F [Gotcha] Component registry typo: STEP_COMPONENTS['acount'] (typo) → undefined.\n",[33,6744,6745],{"class":35,"line":203},[33,6746,6747],{"class":39},"\u002F\u002F Rendering \u003Cundefined \u002F> throws \"Element type is invalid: expected a string or\n",[33,6749,6750],{"class":35,"line":218},[33,6751,6752],{"class":39},"\u002F\u002F a component but got: undefined.\" — one of React's most cryptic errors.\n",[33,6754,6755],{"class":35,"line":248},[33,6756,65],{"emptyLinePlaceholder":64},[33,6758,6759],{"class":35,"line":258},[33,6760,6761],{"class":39},"\u002F\u002F [Gotcha] CSS display:none panels still run effects (useEffect, subscriptions, polling).\n",[33,6763,6764],{"class":35,"line":264},[33,6765,6766],{"class":39},"\u002F\u002F If a hidden panel sets up an interval or WebSocket, it keeps running invisibly.\n",[33,6768,6769],{"class":35,"line":269},[33,6770,6771],{"class":39},"\u002F\u002F Use a \"visible\" prop and guard effects: useEffect(() => { if (!visible) return; ... })\n",[33,6773,6774],{"class":35,"line":274},[33,6775,65],{"emptyLinePlaceholder":64},[33,6777,6778],{"class":35,"line":280},[33,6779,6780],{"class":39},"\u002F\u002F [Gotcha] show\u002Fhide with display:none does not prevent the component from being\n",[33,6782,6783],{"class":35,"line":301},[33,6784,6785],{"class":39},"\u002F\u002F in the accessibility tree. Use aria-hidden=\"true\" on hidden panels, or consider\n",[33,6787,6788],{"class":35,"line":308},[33,6789,6790],{"class":39},"\u002F\u002F conditional rendering for screen-reader-only content.\n",[14,6792,6794],{"id":6793},"spot-the-bug","🧠 Spot the Bug",[5791,6796,6797,6798,6800],{},"A notification badge shows the unread count, but sometimes displays a stray ",[30,6799,1397],{}," on the page:",[19,6802,6804],{"filename":6803,"language":22},"spot_the_bug.js",[24,6805,6807],{"className":26,"code":6806,"language":22,"meta":28,"style":28},"function NotificationBadge({ notifications }) {\n  return (\n    \u003Cnav>\n      \u003Ca href=\"\u002Fhome\">Home\u003C\u002Fa>\n      \u003Ca href=\"\u002Finbox\">\n        Inbox\n        {notifications.length && \u003Csup className=\"badge\">{notifications.length}\u003C\u002Fsup>}\n      \u003C\u002Fa>\n    \u003C\u002Fnav>\n  )\n}\n",[30,6808,6809,6822,6828,6837,6859,6874,6879,6911,6919,6927,6931],{"__ignoreMap":28},[33,6810,6811,6813,6816,6818,6820],{"class":35,"line":36},[33,6812,100],{"class":71},[33,6814,6815],{"class":103}," NotificationBadge",[33,6817,107],{"class":75},[33,6819,3964],{"class":110},[33,6821,114],{"class":75},[33,6823,6824,6826],{"class":35,"line":43},[33,6825,120],{"class":71},[33,6827,187],{"class":75},[33,6829,6830,6832,6835],{"class":35,"line":49},[33,6831,193],{"class":75},[33,6833,6834],{"class":196},"nav",[33,6836,200],{"class":75},[33,6838,6839,6841,6844,6847,6849,6852,6855,6857],{"class":35,"line":55},[33,6840,206],{"class":75},[33,6842,6843],{"class":196},"a",[33,6845,6846],{"class":103}," href",[33,6848,234],{"class":71},[33,6850,6851],{"class":82},"\"\u002Fhome\"",[33,6853,6854],{"class":75},">Home\u003C\u002F",[33,6856,6843],{"class":196},[33,6858,200],{"class":75},[33,6860,6861,6863,6865,6867,6869,6872],{"class":35,"line":61},[33,6862,206],{"class":75},[33,6864,6843],{"class":196},[33,6866,6846],{"class":103},[33,6868,234],{"class":71},[33,6870,6871],{"class":82},"\"\u002Finbox\"",[33,6873,200],{"class":75},[33,6875,6876],{"class":35,"line":68},[33,6877,6878],{"class":75},"        Inbox\n",[33,6880,6881,6884,6886,6888,6890,6893,6895,6897,6899,6902,6904,6907,6909],{"class":35,"line":86},[33,6882,6883],{"class":75},"        {notifications.",[33,6885,523],{"class":132},[33,6887,526],{"class":71},[33,6889,129],{"class":75},[33,6891,6892],{"class":196},"sup",[33,6894,231],{"class":103},[33,6896,234],{"class":71},[33,6898,237],{"class":82},[33,6900,6901],{"class":75},">{notifications.",[33,6903,523],{"class":132},[33,6905,6906],{"class":75},"}\u003C\u002F",[33,6908,6892],{"class":196},[33,6910,245],{"class":75},[33,6912,6913,6915,6917],{"class":35,"line":91},[33,6914,1725],{"class":75},[33,6916,6843],{"class":196},[33,6918,200],{"class":75},[33,6920,6921,6923,6925],{"class":35,"line":97},[33,6922,251],{"class":75},[33,6924,6834],{"class":196},[33,6926,200],{"class":75},[33,6928,6929],{"class":35,"line":117},[33,6930,261],{"class":75},[33,6932,6933],{"class":35,"line":150},[33,6934,153],{"class":75},[6936,6937,6938,6942,6981,6988,7025],"details",{},[6939,6940,6941],"summary",{},"Answer",[5791,6943,6944,6947,6948,6950,6951,6953,6954,6956,6957,6959,6960,6962,6963,6966,6967,6969,6970,6972,6973,293,6975,6977,6978,2675],{},[30,6945,6946],{},"notifications.length && \u003Csup>...\u003C\u002Fsup>"," — when ",[30,6949,3964],{}," is an empty array, ",[30,6952,523],{}," is ",[30,6955,1397],{},". React renders numbers, and ",[30,6958,1397],{}," is a number — so the expression evaluates to ",[30,6961,1397],{},", which React renders as the text ",[30,6964,6965],{},"\"0\""," next to \"Inbox\". The ",[30,6968,224],{}," short-circuits but the falsy value itself (",[30,6971,1397],{},") is still rendered because it's not ",[30,6974,1841],{},[30,6976,5471],{},", or ",[30,6979,6980],{},"undefined",[5791,6982,6983,6987],{},[6984,6985,6986],"strong",{},"Fix",": use an explicit comparison that produces a boolean:",[24,6989,6991],{"className":26,"code":6990,"language":22,"meta":28,"style":28},"{notifications.length > 0 && \u003Csup className=\"badge\">{notifications.length}\u003C\u002Fsup>}\n",[30,6992,6993],{"__ignoreMap":28},[33,6994,6995,6997,6999,7001,7003,7005,7007,7009,7011,7013,7015,7017,7019,7021,7023],{"class":35,"line":36},[33,6996,4098],{"class":75},[33,6998,523],{"class":132},[33,7000,613],{"class":71},[33,7002,616],{"class":132},[33,7004,526],{"class":71},[33,7006,129],{"class":75},[33,7008,6892],{"class":196},[33,7010,231],{"class":103},[33,7012,234],{"class":71},[33,7014,237],{"class":82},[33,7016,6901],{"class":75},[33,7018,523],{"class":132},[33,7020,6906],{"class":75},[33,7022,6892],{"class":196},[33,7024,245],{"class":75},[5791,7026,7027,7030,7031,4440,7033,7035,7036,7038,7039,7042,7043,7045,7046,2675],{},[30,7028,7029],{},"> 0"," evaluates to ",[30,7032,1904],{},[30,7034,1841],{},", and ",[30,7037,1841],{}," is ignored by React (renders nothing). The same trap applies to ",[30,7040,7041],{},"array.filter(...).length && ..."," — always use ",[30,7044,7029],{}," or a ternary with ",[30,7047,5471],{},[14,7049,7051],{"id":7050},"key-takeaways","Key Takeaways",[19,7053,7055],{"filename":7054,"language":22},"key_takeaways.js",[24,7056,7058],{"className":26,"code":7057,"language":22,"meta":28,"style":28},"\u002F\u002F 1. Ternary = 2 branches. && = \"render or nothing\" (use strict boolean, never bare\n\u002F\u002F    .length or a number — 0 renders as \"0\"). Early returns = 3+ whole-component branches.\n\n\u002F\u002F 2. The zero-gotcha: {count && \u003CX \u002F>} renders \"0\" when count is 0. Always use\n\u002F\u002F    {count > 0 && \u003CX \u002F>} or {count ? \u003CX \u002F> : null}.\n\n\u002F\u002F 3. All hooks MUST come before any early return. Hook call count must be constant\n\u002F\u002F    on every render — a hook after a conditional return corrupts hook state.\n\n\u002F\u002F 4. Enum objects replace if\u002Felse chains for N-value lookups — O(1), data-driven,\n\u002F\u002F    trivially extensible. Always provide a ?? fallback for unknown keys.\n\n\u002F\u002F 5. Mount\u002Funmount (conditional render) loses state but saves DOM weight.\n\u002F\u002F    Show\u002Fhide (CSS display) preserves state but keeps all panels in DOM.\n\u002F\u002F    Use the hybrid \"keep visited tabs mounted\" pattern for expensive tabbed UIs.\n\n\u002F\u002F 6. Extract complex inline conditionals to named variables\u002Ffunctions —\n\u002F\u002F    self-documenting, testable, keeps JSX readable. Use useMemo for expensive derivations.\n\n\u002F\u002F 7. Render props are still valid for rendering delegation (component controls when,\n\u002F\u002F    consumer controls how). For pure logic reuse, prefer custom hooks — no extra nesting.\n",[30,7059,7060,7065,7070,7074,7079,7084,7088,7093,7098,7102,7107,7112,7116,7121,7126,7131,7135,7140,7145,7149,7154],{"__ignoreMap":28},[33,7061,7062],{"class":35,"line":36},[33,7063,7064],{"class":39},"\u002F\u002F 1. Ternary = 2 branches. && = \"render or nothing\" (use strict boolean, never bare\n",[33,7066,7067],{"class":35,"line":43},[33,7068,7069],{"class":39},"\u002F\u002F    .length or a number — 0 renders as \"0\"). Early returns = 3+ whole-component branches.\n",[33,7071,7072],{"class":35,"line":49},[33,7073,65],{"emptyLinePlaceholder":64},[33,7075,7076],{"class":35,"line":55},[33,7077,7078],{"class":39},"\u002F\u002F 2. The zero-gotcha: {count && \u003CX \u002F>} renders \"0\" when count is 0. Always use\n",[33,7080,7081],{"class":35,"line":61},[33,7082,7083],{"class":39},"\u002F\u002F    {count > 0 && \u003CX \u002F>} or {count ? \u003CX \u002F> : null}.\n",[33,7085,7086],{"class":35,"line":68},[33,7087,65],{"emptyLinePlaceholder":64},[33,7089,7090],{"class":35,"line":86},[33,7091,7092],{"class":39},"\u002F\u002F 3. All hooks MUST come before any early return. Hook call count must be constant\n",[33,7094,7095],{"class":35,"line":91},[33,7096,7097],{"class":39},"\u002F\u002F    on every render — a hook after a conditional return corrupts hook state.\n",[33,7099,7100],{"class":35,"line":97},[33,7101,65],{"emptyLinePlaceholder":64},[33,7103,7104],{"class":35,"line":117},[33,7105,7106],{"class":39},"\u002F\u002F 4. Enum objects replace if\u002Felse chains for N-value lookups — O(1), data-driven,\n",[33,7108,7109],{"class":35,"line":150},[33,7110,7111],{"class":39},"\u002F\u002F    trivially extensible. Always provide a ?? fallback for unknown keys.\n",[33,7113,7114],{"class":35,"line":156},[33,7115,65],{"emptyLinePlaceholder":64},[33,7117,7118],{"class":35,"line":161},[33,7119,7120],{"class":39},"\u002F\u002F 5. Mount\u002Funmount (conditional render) loses state but saves DOM weight.\n",[33,7122,7123],{"class":35,"line":167},[33,7124,7125],{"class":39},"\u002F\u002F    Show\u002Fhide (CSS display) preserves state but keeps all panels in DOM.\n",[33,7127,7128],{"class":35,"line":182},[33,7129,7130],{"class":39},"\u002F\u002F    Use the hybrid \"keep visited tabs mounted\" pattern for expensive tabbed UIs.\n",[33,7132,7133],{"class":35,"line":190},[33,7134,65],{"emptyLinePlaceholder":64},[33,7136,7137],{"class":35,"line":203},[33,7138,7139],{"class":39},"\u002F\u002F 6. Extract complex inline conditionals to named variables\u002Ffunctions —\n",[33,7141,7142],{"class":35,"line":218},[33,7143,7144],{"class":39},"\u002F\u002F    self-documenting, testable, keeps JSX readable. Use useMemo for expensive derivations.\n",[33,7146,7147],{"class":35,"line":248},[33,7148,65],{"emptyLinePlaceholder":64},[33,7150,7151],{"class":35,"line":258},[33,7152,7153],{"class":39},"\u002F\u002F 7. Render props are still valid for rendering delegation (component controls when,\n",[33,7155,7156],{"class":35,"line":264},[33,7157,7158],{"class":39},"\u002F\u002F    consumer controls how). For pure logic reuse, prefer custom hooks — no extra nesting.\n",[3698,7160,7161],{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}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 .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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 .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);}",{"title":28,"searchDepth":43,"depth":43,"links":7163},[7164,7165,7166,7169,7170,7171,7172,7173,7174,7175,7176,7177],{"id":16,"depth":43,"text":17},{"id":473,"depth":43,"text":474},{"id":1047,"depth":43,"text":1048,"children":7167},[7168],{"id":1752,"depth":49,"text":1753},{"id":2093,"depth":43,"text":2094},{"id":2927,"depth":43,"text":2928},{"id":3914,"depth":43,"text":3915},{"id":5314,"depth":43,"text":5315},{"id":6157,"depth":43,"text":6158},{"id":6540,"depth":43,"text":6541},{"id":6657,"depth":43,"text":6658},{"id":6793,"depth":43,"text":6794},{"id":7050,"depth":43,"text":7051},"Ternary, &&, IIFE, early returns, enum lookups, show\u002Fhide vs mount\u002Funmount, extracting conditional logic — production-grade patterns and anti-patterns for mid-to-senior React engineers.","md",{},"\u002Freact\u002F12-conditional-rendering-patterns",{"title":5,"description":7178},"react\u002F12-conditional-rendering-patterns","jv8tnl7TxEN4MbIJgluYRi-7QsaZaBkbw4E79IfM1oo",1789924652205]