[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fstate":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fstate":753,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fstate":779},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":749,"stem":750,"id":751,"extension":752},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fstate","状态管理","React 组件内 state 用 Hooks；跨组件共享状态可选 Context、Redux Toolkit、Zustand 等。见 Context Hook。","技能小册",[12,13],"react","state","2024-02-07",false,{"type":17,"value":18,"toc":742},"minimark",[19,22,44,48,118,135,139,147,401,414,417,420,614,625,629,636,661,672,675,678,738],[20,21,8],"h1",{"id":8},[23,24,25,26,30,31,30,34,37,38,43],"p",{},"React 组件内 state 用 Hooks；跨组件共享状态可选 ",[27,28,29],"strong",{},"Context","、",[27,32,33],{},"Redux Toolkit",[27,35,36],{},"Zustand"," 等。见 ",[39,40,42],"a",{"href":41},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fhooks\u002Fcontext","Context Hook","。",[45,46,47],"h2",{"id":47},"选型简表",[49,50,51,64],"table",{},[52,53,54],"thead",{},[55,56,57,61],"tr",{},[58,59,60],"th",{},"场景",[58,62,63],{},"建议",[65,66,67,76,83,96,107],"tbody",{},[55,68,69,73],{},[70,71,72],"td",{},"父子\u002F兄弟局部共享",[70,74,75],{},"提升 state + props",[55,77,78,81],{},[70,79,80],{},"主题、语言、当前用户（低频）",[70,82,29],{},[55,84,85,88],{},[70,86,87],{},"服务端列表\u002F详情、缓存、重试",[70,89,90],{},[39,91,95],{"href":92,"rel":93},"https:\u002F\u002Ftanstack.com\u002Fquery",[94],"nofollow","TanStack Query",[55,97,98,101],{},[70,99,100],{},"复杂客户端全局状态、可预测更新",[70,102,103],{},[39,104,33],{"href":105,"rel":106},"https:\u002F\u002Fredux-toolkit.js.org\u002F",[94],[55,108,109,112],{},[70,110,111],{},"中小型全局状态、API 简单",[70,113,114],{},[39,115,36],{"href":116,"rel":117},"https:\u002F\u002Fzustand.docs.pmnd.rs\u002F",[94],[23,119,120,121,124,125,128,129,134],{},"勿把所有数据放入全局 store；",[27,122,123],{},"服务端状态","与",[27,126,127],{},"客户端 UI 状态","分离是常见架构原则（见 Redux 官方 ",[39,130,133],{"href":131,"rel":132},"https:\u002F\u002Fredux.js.org\u002Ftutorials\u002Fessentials\u002Fpart-5-async-logic#client-state-vs-server-state",[94],"服务端状态 vs 客户端状态"," 说明）。",[45,136,138],{"id":137},"redux-toolkitrtk","Redux Toolkit（RTK）",[23,140,141,142,146],{},"官方推荐的 Redux 写法，内置 Immer、异步 ",[143,144,145],"code",{},"createAsyncThunk","、DevTools。",[148,149,154],"pre",{"className":150,"code":151,"language":152,"meta":153,"style":153},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","import { configureStore, createSlice } from \"@reduxjs\u002Ftoolkit\";\n\nconst counterSlice = createSlice({\n  name: \"counter\",\n  initialState: { value: 0 },\n  reducers: {\n    increment(state) {\n      state.value += 1;\n    },\n  },\n});\n\nexport const store = configureStore({\n  reducer: { counter: counterSlice.reducer },\n});\n","ts","",[143,155,156,199,206,230,250,272,283,300,320,326,332,342,347,367,392],{"__ignoreMap":153},[157,158,161,165,169,173,176,179,182,185,189,193,196],"span",{"class":159,"line":160},"line",1,[157,162,164],{"class":163},"sVHd0","import",[157,166,168],{"class":167},"sP7_E"," {",[157,170,172],{"class":171},"su5hD"," configureStore",[157,174,175],{"class":167},",",[157,177,178],{"class":171}," createSlice",[157,180,181],{"class":167}," }",[157,183,184],{"class":163}," from",[157,186,188],{"class":187},"sjJ54"," \"",[157,190,192],{"class":191},"s_sjI","@reduxjs\u002Ftoolkit",[157,194,195],{"class":187},"\"",[157,197,198],{"class":167},";\n",[157,200,202],{"class":159,"line":201},2,[157,203,205],{"emptyLinePlaceholder":204},true,"\n",[157,207,209,213,217,221,224,227],{"class":159,"line":208},3,[157,210,212],{"class":211},"sbsja","const",[157,214,216],{"class":215},"s_hVV"," counterSlice",[157,218,220],{"class":219},"smGrS"," =",[157,222,178],{"class":223},"sGLFI",[157,225,226],{"class":171},"(",[157,228,229],{"class":167},"{\n",[157,231,233,237,240,242,245,247],{"class":159,"line":232},4,[157,234,236],{"class":235},"skxfh","  name",[157,238,239],{"class":167},":",[157,241,188],{"class":187},[157,243,244],{"class":191},"counter",[157,246,195],{"class":187},[157,248,249],{"class":167},",\n",[157,251,253,256,258,260,263,265,269],{"class":159,"line":252},5,[157,254,255],{"class":235},"  initialState",[157,257,239],{"class":167},[157,259,168],{"class":167},[157,261,262],{"class":235}," value",[157,264,239],{"class":167},[157,266,268],{"class":267},"srdBf"," 0",[157,270,271],{"class":167}," },\n",[157,273,275,278,280],{"class":159,"line":274},6,[157,276,277],{"class":235},"  reducers",[157,279,239],{"class":167},[157,281,282],{"class":167}," {\n",[157,284,286,290,292,295,298],{"class":159,"line":285},7,[157,287,289],{"class":288},"sVXei","    increment",[157,291,226],{"class":167},[157,293,13],{"class":294},"s99_P",[157,296,297],{"class":167},")",[157,299,282],{"class":167},[157,301,303,306,309,312,315,318],{"class":159,"line":302},8,[157,304,305],{"class":171},"      state",[157,307,308],{"class":167},".",[157,310,311],{"class":171},"value",[157,313,314],{"class":219}," +=",[157,316,317],{"class":267}," 1",[157,319,198],{"class":167},[157,321,323],{"class":159,"line":322},9,[157,324,325],{"class":167},"    },\n",[157,327,329],{"class":159,"line":328},10,[157,330,331],{"class":167},"  },\n",[157,333,335,338,340],{"class":159,"line":334},11,[157,336,337],{"class":167},"}",[157,339,297],{"class":171},[157,341,198],{"class":167},[157,343,345],{"class":159,"line":344},12,[157,346,205],{"emptyLinePlaceholder":204},[157,348,350,353,356,359,361,363,365],{"class":159,"line":349},13,[157,351,352],{"class":163},"export",[157,354,355],{"class":211}," const",[157,357,358],{"class":215}," store",[157,360,220],{"class":219},[157,362,172],{"class":223},[157,364,226],{"class":171},[157,366,229],{"class":167},[157,368,370,373,375,377,380,382,384,386,389],{"class":159,"line":369},14,[157,371,372],{"class":235},"  reducer",[157,374,239],{"class":167},[157,376,168],{"class":167},[157,378,379],{"class":235}," counter",[157,381,239],{"class":167},[157,383,216],{"class":171},[157,385,308],{"class":167},[157,387,388],{"class":171},"reducer ",[157,390,391],{"class":167},"},\n",[157,393,395,397,399],{"class":159,"line":394},15,[157,396,337],{"class":167},[157,398,297],{"class":171},[157,400,198],{"class":167},[23,402,403,404,407,408,30,411,43],{},"组件侧使用 ",[143,405,406],{},"react-redux"," 的 ",[143,409,410],{},"useSelector",[143,412,413],{},"useDispatch",[45,415,36],{"id":416},"zustand",[23,418,419],{},"极简 store，无 Provider 包裹（除非需要 SSR 等）：",[148,421,423],{"className":150,"code":422,"language":152,"meta":153,"style":153},"import { create } from \"zustand\";\n\ntype BearStore = {\n  bears: number;\n  increase: () => void;\n};\n\nexport const useBearStore = create\u003CBearStore>((set) => ({\n  bears: 0,\n  increase: () => set((s) => ({ bears: s.bears + 1 })),\n}));\n",[143,424,425,446,450,463,477,495,500,504,542,552,606],{"__ignoreMap":153},[157,426,427,429,431,434,436,438,440,442,444],{"class":159,"line":160},[157,428,164],{"class":163},[157,430,168],{"class":167},[157,432,433],{"class":171}," create",[157,435,181],{"class":167},[157,437,184],{"class":163},[157,439,188],{"class":187},[157,441,416],{"class":191},[157,443,195],{"class":187},[157,445,198],{"class":167},[157,447,448],{"class":159,"line":201},[157,449,205],{"emptyLinePlaceholder":204},[157,451,452,455,459,461],{"class":159,"line":208},[157,453,454],{"class":211},"type",[157,456,458],{"class":457},"sbgvK"," BearStore",[157,460,220],{"class":219},[157,462,282],{"class":167},[157,464,465,469,471,475],{"class":159,"line":232},[157,466,468],{"class":467},"sucvu","  bears",[157,470,239],{"class":219},[157,472,474],{"class":473},"sZMiF"," number",[157,476,198],{"class":167},[157,478,479,482,484,487,490,493],{"class":159,"line":252},[157,480,481],{"class":288},"  increase",[157,483,239],{"class":219},[157,485,486],{"class":167}," ()",[157,488,489],{"class":211}," =>",[157,491,492],{"class":473}," void",[157,494,198],{"class":167},[157,496,497],{"class":159,"line":274},[157,498,499],{"class":167},"};\n",[157,501,502],{"class":159,"line":285},[157,503,205],{"emptyLinePlaceholder":204},[157,505,506,508,510,513,515,517,520,523,526,528,530,533,535,537,540],{"class":159,"line":302},[157,507,352],{"class":163},[157,509,355],{"class":211},[157,511,512],{"class":215}," useBearStore",[157,514,220],{"class":219},[157,516,433],{"class":223},[157,518,519],{"class":167},"\u003C",[157,521,522],{"class":457},"BearStore",[157,524,525],{"class":167},">",[157,527,226],{"class":171},[157,529,226],{"class":167},[157,531,532],{"class":294},"set",[157,534,297],{"class":167},[157,536,489],{"class":211},[157,538,539],{"class":171}," (",[157,541,229],{"class":167},[157,543,544,546,548,550],{"class":159,"line":322},[157,545,468],{"class":235},[157,547,239],{"class":167},[157,549,268],{"class":267},[157,551,249],{"class":167},[157,553,554,556,558,560,562,565,567,569,572,574,576,578,581,584,586,589,591,594,597,599,601,604],{"class":159,"line":328},[157,555,481],{"class":223},[157,557,239],{"class":167},[157,559,486],{"class":167},[157,561,489],{"class":211},[157,563,564],{"class":223}," set",[157,566,226],{"class":171},[157,568,226],{"class":167},[157,570,571],{"class":294},"s",[157,573,297],{"class":167},[157,575,489],{"class":211},[157,577,539],{"class":171},[157,579,580],{"class":167},"{",[157,582,583],{"class":235}," bears",[157,585,239],{"class":167},[157,587,588],{"class":171}," s",[157,590,308],{"class":167},[157,592,593],{"class":171},"bears ",[157,595,596],{"class":219},"+",[157,598,317],{"class":267},[157,600,181],{"class":167},[157,602,603],{"class":171},"))",[157,605,249],{"class":167},[157,607,608,610,612],{"class":159,"line":334},[157,609,337],{"class":167},[157,611,603],{"class":171},[157,613,198],{"class":167},[148,615,619],{"className":616,"code":617,"language":618,"meta":153,"style":153},"language-tsx shiki shiki-themes material-theme-lighter github-light github-dark","const bears = useBearStore((s) => s.bears);\n","tsx",[143,620,621],{"__ignoreMap":153},[157,622,623],{"class":159,"line":160},[157,624,617],{},[45,626,628],{"id":627},"tanstack-query服务端状态","TanStack Query（服务端状态）",[23,630,631,632,635],{},"管理 ",[143,633,634],{},"fetch"," 的 loading、error、缓存、失效与重新请求：",[148,637,639],{"className":616,"code":638,"language":618,"meta":153,"style":153},"const { data, isPending, error } = useQuery({\n  queryKey: [\"user\", userId],\n  queryFn: () => fetchUser(userId),\n});\n",[143,640,641,646,651,656],{"__ignoreMap":153},[157,642,643],{"class":159,"line":160},[157,644,645],{},"const { data, isPending, error } = useQuery({\n",[157,647,648],{"class":159,"line":201},[157,649,650],{},"  queryKey: [\"user\", userId],\n",[157,652,653],{"class":159,"line":208},[157,654,655],{},"  queryFn: () => fetchUser(userId),\n",[157,657,658],{"class":159,"line":232},[157,659,660],{},"});\n",[23,662,663,664,667,668,671],{},"与 Redux 互补：Query 管",[27,665,666],{},"远程数据","，Redux\u002FZustand 管",[27,669,670],{},"纯客户端","状态。",[45,673,674],{"id":674},"参考文献",[23,676,677],{},"以下链接在编写时均可正常访问：",[49,679,680,690],{},[52,681,682],{},[55,683,684,687],{},[58,685,686],{},"资料",[58,688,689],{},"说明",[65,691,692,703,715,726],{},[55,693,694,700],{},[70,695,696],{},[39,697,699],{"href":105,"rel":698},[94],"Redux Toolkit 文档",[70,701,702],{},"RTK（英文）",[55,704,705,712],{},[70,706,707],{},[39,708,711],{"href":709,"rel":710},"https:\u002F\u002Freact-redux.js.org\u002F",[94],"React Redux",[70,713,714],{},"绑定 React",[55,716,717,723],{},[70,718,719],{},[39,720,722],{"href":116,"rel":721},[94],"Zustand 文档",[70,724,725],{},"英文",[55,727,728,735],{},[70,729,730],{},[39,731,734],{"href":732,"rel":733},"https:\u002F\u002Ftanstack.com\u002Fquery\u002Flatest\u002Fdocs\u002Fframework\u002Freact\u002Foverview",[94],"TanStack Query 文档",[70,736,737],{},"React 集成",[739,740,741],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":153,"searchDepth":201,"depth":201,"links":743},[744,745,746,747,748],{"id":47,"depth":201,"text":47},{"id":137,"depth":201,"text":138},{"id":416,"depth":201,"text":36},{"id":627,"depth":201,"text":628},{"id":674,"depth":201,"text":674},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fframe\u002FReact\u002Fstate","knowledge\u002Fknowledge\u002Fbooklet\u002Fframe\u002FReact\u002Fstate.md","md",{"items":754},[755,759,763,767,771,775],{"path":756,"title":757,"description":758,"category":10,"score":322},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fhooks\u002Fstate","State 与 Reducer","Hooks 让函数组件拥有 state 与副作用能力。本文介绍 useState 与 useReducer。见 React 基础。",{"path":760,"title":761,"description":762,"category":10,"score":274},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Frendering","渲染与协调","React 将组件渲染为虚拟 DOM 树，再协调（reconciliation）到浏览器 DOM。理解该过程有助于解释 key、memo 与性能优化。涵盖渲染流程、Fiber、startTransition、Suspense、最佳实践与常见坑。",{"path":764,"title":765,"description":766,"category":10,"score":274},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fproject","工程化","新建 React 项目时，官方与社区主流工具为 Vite；全栈场景常用 Next.js。涵盖 Vite + React、Create React App 现状、Next.js、目录结构、环境变量、部署、最佳实践与常见坑。",{"path":768,"title":769,"description":770,"category":10,"score":274},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Ftypescript","TypeScript","React 官方推荐 TypeScript。类型主要落在 Props、事件、Ref 与 Hooks 返回值上。见 组件。",{"path":772,"title":773,"description":774,"category":10,"score":274},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Ftest","测试","React 组件测试推荐 React Testing Library（RTL）：从用户可见行为断言，而非实现细节。运行器常用 Vitest 或 Jest。涵盖安装配置、查询优先级、异步测试、Mock 网络请求、最佳实践与常见坑。",{"path":776,"title":777,"description":778,"category":10,"score":274},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fperformance\u002Fbuild","构建与分包","通过代码分割与构建配置减小首屏 JavaScript 体积。涵盖 React.lazy\u002FSuspense、路由级分割、Tree Shaking、Vite 生产构建、体积分析、最佳实践与常见坑。运行时优化见 runtime。",{"series":780,"title":12,"items":781,"index":349,"prev":829,"next":830},"booklet\u002Fframe\u002Freact",[782,786,788,792,794,798,802,806,810,812,814,818,822,824,825,827],{"path":783,"title":784,"date":785,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fbasics","React 基础","2020-02-12",{"path":776,"title":777,"date":787,"pinned":15},"2025-07-23",{"path":789,"title":790,"date":791,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fcomponents","组件与 Props","2020-06-11",{"path":41,"title":29,"date":793,"pinned":15},"2021-10-16",{"path":795,"title":796,"date":797,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fecology","生态","2023-02-04",{"path":799,"title":800,"date":801,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fhooks\u002Feffect","Effect 与副作用","2024-10-11",{"path":803,"title":804,"date":805,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fjsx","JSX 与语法","2020-02-29",{"path":807,"title":808,"date":809,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fhooks\u002Fmemo","Memo、Callback 与 Ref","2021-02-28",{"path":764,"title":765,"date":811,"pinned":15},"2026-05-08",{"path":760,"title":761,"date":813,"pinned":15},"2026-07-10",{"path":815,"title":816,"date":817,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Frouter","路由","2023-09-06",{"path":819,"title":820,"date":821,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Freact\u002Fperformance\u002Fruntime","运行时优化","2020-02-05",{"path":756,"title":757,"date":823,"pinned":15},"2021-02-21",{"path":7,"title":8,"date":14,"pinned":15},{"path":772,"title":773,"date":826,"pinned":15},"2025-09-26",{"path":768,"title":769,"date":828,"pinned":15},"2026-03-13",{"path":756,"title":757,"date":823,"pinned":15},{"path":772,"title":773,"date":826,"pinned":15}]