[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"i-ri:search-line":3,"i-ri:moon-line":8,"i-ri:sun-line":10,"i-ri:menu-3-line":12,"i-ri:close-line":14,"notes-module-items-react":16,"notes-page-react-11-data-layer\u002F01-state-layering-ui-server-url-global":494,"i-ri:arrow-left-s-line":1517,"i-ri:menu-2-line":1519,"i-ri:arrow-right-s-line":1521,"i-ep:copy-document":1523},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"currentColor\" d=\"M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2h.1A6.98 6.98 0 0 0 10 7m-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938A8 8 0 0 0 4 12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"currentColor\" d=\"M12 18a6 6 0 1 1 0-12a6 6 0 0 1 0 12m0-2a4 4 0 1 0 0-8a4 4 0 0 0 0 8M11 1h2v3h-2zm0 19h2v3h-2zM3.515 4.929l1.414-1.414L7.05 5.636L5.636 7.05zM16.95 18.364l1.414-1.414l2.121 2.121l-1.414 1.414zm2.121-14.85l1.414 1.415l-2.121 2.121l-1.414-1.414zM5.636 16.95l1.414 1.414l-2.121 2.121l-1.414-1.414zM23 11v2h-3v-2zM4 11v2H1v-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm6 7h12v2H9zm-6 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"currentColor\" d=\"m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z\"\u002F>",[17,22,26,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290,294,298,302,306,310,314,318,322,326,330,334,338,342,346,350,354,358,362,366,370,374,378,382,386,390,394,398,402,406,410,414,418,422,426,430,434,438,442,446,450,454,458,462,466,470,474,478,482,486,490],{"path":18,"title":19,"meta":20},"\u002Fnotes\u002Freact\u002F01-basics\u002F01-how-to-read-this-repo","如何阅读本仓库（学习路径与章节依赖）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},"2026-11-05T09:47:15.000Z",{"path":23,"title":24,"meta":25},"\u002Fnotes\u002Freact\u002F01-basics\u002F02-render-vs-commit","React 渲染两阶段：Render vs Commit（总览）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":27,"title":28,"meta":29},"\u002Fnotes\u002Freact\u002F01-basics\u002F03-update-pipeline-birdview","从“更新”到“页面变更”：一次 setState 的全链路鸟瞰",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":31,"title":32,"meta":33},"\u002Fnotes\u002Freact\u002F01-basics","基础入门（建议先读）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":35,"title":36,"meta":37},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F01-browser-multi-process","浏览器多进程架构",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":39,"title":40,"meta":41},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F02-event-loop-overview","事件循环概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":43,"title":44,"meta":45},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F03-call-stack","函数调用栈",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":47,"title":48,"meta":49},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F04-threads","线程介绍",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":51,"title":52,"meta":53},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F05-refresh-rate-and-queues","刷新率与执行队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":55,"title":56,"meta":57},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F06-settimeout","setTimeout 原理详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":59,"title":60,"meta":61},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F07-promise","Promise 原理详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":63,"title":64,"meta":65},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F08-event-loop-in-practice","事件循环机制（综合）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":67,"title":68,"meta":69},"\u002Fnotes\u002Freact\u002F02-event-loop\u002F09-priority-queues","优先级队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":71,"title":72,"meta":73},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F01-concept","并发模式：概念",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":75,"title":76,"meta":77},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F02-demo","案例演示并发模式",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":79,"title":80,"meta":81},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F03-high-priority-preemption","高优先级插队",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":83,"title":84,"meta":85},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F04-preemption-vs-interruption","插队的影响、与中断的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":87,"title":88,"meta":89},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F05-shouldYield","中断条件：shouldYield",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":91,"title":92,"meta":93},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F06-react-tasks-and-queues","React 中的任务与队列",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":95,"title":96,"meta":97},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F07-ensureRootIsScheduled","ensureRootIsScheduled",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":99,"title":100,"meta":101},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F08-batch-updates-merge","合并多个更新触发",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":103,"title":104,"meta":105},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F09-taskQueue-lifecycle","taskQueue 队列循环的启动与结束",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":107,"title":108,"meta":109},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F10-time-slicing","时间切片是如何实现的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":111,"title":112,"meta":113},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F11-workLoop-full","workLoop 循环完整逻辑",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":115,"title":116,"meta":117},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F12-priority-design","React 中的优先级设计",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":119,"title":120,"meta":121},"\u002Fnotes\u002Freact\u002F03-concurrent-mode\u002F13-lane-model","lane 模型",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":123,"title":124,"meta":125},"\u002Fnotes\u002Freact\u002F04-fiber\u002F01-three-node-types","三种节点对象",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":127,"title":128,"meta":129},"\u002Fnotes\u002Freact\u002F04-fiber\u002F02-fiberRootNode","FiberRootNode",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":131,"title":132,"meta":133},"\u002Fnotes\u002Freact\u002F04-fiber\u002F03-fiber-tree","Fiber 树",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":135,"title":136,"meta":137},"\u002Fnotes\u002Freact\u002F04-fiber\u002F04-initial-mount-build","Fiber 树初始构建过程",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":139,"title":140,"meta":141},"\u002Fnotes\u002Freact\u002F04-fiber\u002F05-workLoopConcurrent","workLoopConcurrent",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":143,"title":144,"meta":145},"\u002Fnotes\u002Freact\u002F04-fiber\u002F06-stack-and-workInProgress","栈结构 与 workInProgress",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":147,"title":148,"meta":149},"\u002Fnotes\u002Freact\u002F04-fiber\u002F07-executionContext","执行上下文 executionContext",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":151,"title":152,"meta":153},"\u002Fnotes\u002Freact\u002F04-fiber\u002F08-update-lanes","update lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":155,"title":156,"meta":157},"\u002Fnotes\u002Freact\u002F04-fiber\u002F09-render-lanes","render lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":159,"title":160,"meta":161},"\u002Fnotes\u002Freact\u002F04-fiber\u002F10-fiber-lanes","fiber lanes",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":163,"title":164,"meta":165},"\u002Fnotes\u002Freact\u002F04-fiber\u002F11-flags-appendix","附录：flags",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":167,"title":168,"meta":169},"\u002Fnotes\u002Freact\u002F05-hooks\u002F01-background","hook 背景",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":171,"title":172,"meta":173},"\u002Fnotes\u002Freact\u002F05-hooks\u002F02-categories","hook 分类",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":175,"title":176,"meta":177},"\u002Fnotes\u002Freact\u002F05-hooks\u002F03-closures","hook 与闭包",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":179,"title":180,"meta":181},"\u002Fnotes\u002Freact\u002F05-hooks\u002F04-hooks-and-fiber","hook 与 fiber",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":183,"title":184,"meta":185},"\u002Fnotes\u002Freact\u002F05-hooks\u002F05-renderWithHooks","renderWithHooks",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":187,"title":188,"meta":189},"\u002Fnotes\u002Freact\u002F05-hooks\u002F06-init-state-hook","初始化 State Hook",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":191,"title":192,"meta":193},"\u002Fnotes\u002Freact\u002F05-hooks\u002F07-init-effect-hook","初始化 effect Hook",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":195,"title":196,"meta":197},"\u002Fnotes\u002Freact\u002F05-hooks\u002F08-circular-linked-list","环形链表详解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":199,"title":200,"meta":201},"\u002Fnotes\u002Freact\u002F05-hooks\u002F09-useReducer-vs-useState","useReducer 与 useState 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":203,"title":204,"meta":205},"\u002Fnotes\u002Freact\u002F05-hooks\u002F10-update-linked-list","update 链表",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":207,"title":208,"meta":209},"\u002Fnotes\u002Freact\u002F05-hooks\u002F11-mount-state-updates","初始阶段的状态更新",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":211,"title":212,"meta":213},"\u002Fnotes\u002Freact\u002F05-hooks\u002F12-baseQueue-vs-pending","baseQueue 与 queue.pending",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":215,"title":216,"meta":217},"\u002Fnotes\u002Freact\u002F05-hooks\u002F13-dispatch-in-update","更新阶段的 dispatch",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":219,"title":220,"meta":221},"\u002Fnotes\u002Freact\u002F05-hooks\u002F14-commitRoot","commitRoot",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":223,"title":224,"meta":225},"\u002Fnotes\u002Freact\u002F06-diff\u002F01-update-overview","React 更新机制概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":227,"title":228,"meta":229},"\u002Fnotes\u002Freact\u002F06-diff\u002F02-diff-strategy","diff 策略",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":231,"title":232,"meta":233},"\u002Fnotes\u002Freact\u002F06-diff\u002F03-node-compare","节点比较方式",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":235,"title":236,"meta":237},"\u002Fnotes\u002Freact\u002F06-diff\u002F04-reconcileChildFibers","reconcileChildFibers",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":239,"title":240,"meta":241},"\u002Fnotes\u002Freact\u002F06-diff\u002F05-reconcileSingleElement","reconcileSingleElement",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":243,"title":244,"meta":245},"\u002Fnotes\u002Freact\u002F06-diff\u002F06-reconcileChildrenArray","reconcileChildrenArray",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":247,"title":248,"meta":249},"\u002Fnotes\u002Freact\u002F06-diff\u002F07-why-not-number-key","为什么不建议使用数字作为 key",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":251,"title":252,"meta":253},"\u002Fnotes\u002Freact\u002F07-event-system\u002F01-overview","事件系统概述",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":255,"title":256,"meta":257},"\u002Fnotes\u002Freact\u002F07-event-system\u002F02-event-plugin","事件插件",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":259,"title":260,"meta":261},"\u002Fnotes\u002Freact\u002F07-event-system\u002F03-event-pooling","事件池",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":263,"title":264,"meta":265},"\u002Fnotes\u002Freact\u002F07-event-system\u002F04-root-listeners","根节点事件绑定",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":267,"title":268,"meta":269},"\u002Fnotes\u002Freact\u002F07-event-system\u002F05-event-dispatch","事件触发",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":271,"title":272,"meta":273},"\u002Fnotes\u002Freact\u002F08-interview\u002F01-useEffect-vs-useLayoutEffect","useEffect 与 useLayoutEffect 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":275,"title":276,"meta":277},"\u002Fnotes\u002Freact\u002F08-interview\u002F02-why-no-conditional-hooks","为什么 hook 不能写在条件判断里",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":279,"title":280,"meta":281},"\u002Fnotes\u002Freact\u002F08-interview\u002F03-understanding-concurrency","聊聊在 React 中，你对并发模式的理解",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":283,"title":284,"meta":285},"\u002Fnotes\u002Freact\u002F08-interview\u002F04-update-mechanism","聊聊 React 的更新机制原理",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":287,"title":288,"meta":289},"\u002Fnotes\u002Freact\u002F08-interview\u002F05-setState-sync-or-async","setState 是同步还是异步的？",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":291,"title":292,"meta":293},"\u002Fnotes\u002Freact\u002F08-interview\u002F06-useState-vs-useReducer","聊聊 useState 与 useReducer 的区别",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":295,"title":296,"meta":297},"\u002Fnotes\u002Freact\u002F08-interview\u002F07-closure-trap","聊聊闭包陷阱问题，以及如何解决",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":299,"title":300,"meta":301},"\u002Fnotes\u002Freact\u002F08-interview\u002F08-time-slicing-details","时间分片是如何实现的（任务拆分\u002F中断\u002F恢复）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":303,"title":304,"meta":305},"\u002Fnotes\u002Freact\u002F08-interview\u002F09-batched-updates-useState","聊聊 useState 的批处理更新机制",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":307,"title":308,"meta":309},"\u002Fnotes\u002Freact\u002F08-interview\u002F10-jsx-to-dom","JSX 是如何转变成为真实 DOM 的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":311,"title":312,"meta":313},"\u002Fnotes\u002Freact\u002F08-interview\u002F11-useCallback-impl","useCallback 的实现原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":315,"title":316,"meta":317},"\u002Fnotes\u002Freact\u002F08-interview\u002F12-scheduling-mechanism","详细聊聊 React 的调度机制",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":319,"title":320,"meta":321},"\u002Fnotes\u002Freact\u002F08-interview\u002F13-priority-and-lanes","聊聊 React 的优先级机制（Lane 模型）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":323,"title":324,"meta":325},"\u002Fnotes\u002Freact\u002F08-interview\u002F14-diff-algorithm","React 的 Diff 算法是什么样的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":327,"title":328,"meta":329},"\u002Fnotes\u002Freact\u002F08-interview\u002F15-event-system","详细聊聊 React 的事件系统是如何实现的",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":331,"title":332,"meta":333},"\u002Fnotes\u002Freact\u002F08-interview\u002F16-portals-bubbling","React Portals 上的事件是否会冒泡到父组件，原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":335,"title":336,"meta":337},"\u002Fnotes\u002Freact\u002F08-interview\u002F17-useEffect-impl","useEffect 的实现原理是什么",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":339,"title":340,"meta":341},"\u002Fnotes\u002Freact\u002F08-interview\u002F18-useContext-impl","请聊聊 useContext 的实现原理",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":343,"title":344,"meta":345},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F01-automatic-batching-and-flushsync","React 18 自动批处理（Automatic Batching）与 flushSync",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":347,"title":348,"meta":349},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F02-strictmode-and-idempotent-effects","React StrictMode：为什么会“双调用”？（源码\u002F机制视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":351,"title":352,"meta":353},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F03-transition-useTransition-useDeferredValue","Transition：startTransition \u002F useTransition \u002F useDeferredValue（机制视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":355,"title":356,"meta":357},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F04-suspense-loading-boundary-design","Suspense：加载态边界如何设计（机制\u002F架构视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":359,"title":360,"meta":361},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice\u002F05-error-boundary-reporting-and-recovery","Error Boundary：兜底、重试与上报（自研 vs Sentry）（机制\u002F架构视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":363,"title":364,"meta":365},"\u002Fnotes\u002Freact\u002F09-react-18-in-practice","React 18 实战（并发特性与默认行为）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":367,"title":368,"meta":369},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F01-routing-and-url-state-mental-model","路由与 URL State：统一心智模型（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":371,"title":372,"meta":373},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F02-tanstack-router-route-tree-search-loader-prefetch","TanStack Router（Vite \u002F SPA）：Route Tree \u002F Search \u002F Loader \u002F Prefetch（落地篇）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":375,"title":376,"meta":377},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation\u002F03-next-app-router-segments-layout-loading-error-not-found-prefetch","Next.js App Router：Segments \u002F Layouts \u002F Loading-Error-NotFound \u002F Prefetch（落地篇）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":379,"title":380,"meta":381},"\u002Fnotes\u002Freact\u002F10-routing-and-navigation","路由与导航（TanStack Router \u002F Next App Router）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":383,"title":384,"meta":385},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F01-state-layering-ui-server-url-global","状态分层：UI \u002F Server \u002F URL \u002F Global（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":387,"title":388,"meta":389},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F02-tanstack-query-caching-and-invalidation","TanStack Query：缓存模型与失效策略（Caching & Invalidation）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":391,"title":392,"meta":393},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F03-optimistic-updates-and-consistency","TanStack Query：乐观更新与一致性（Optimistic Updates & Consistency）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":395,"title":396,"meta":397},"\u002Fnotes\u002Freact\u002F11-data-layer\u002F04-form-architecture-react-hook-form-validation-performance-testability","表单架构：React Hook Form 的受控\u002F非受控、校验、性能与可测试性（架构师视角）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":399,"title":400,"meta":401},"\u002Fnotes\u002Freact\u002F11-data-layer","数据层（Server State \u002F 表单 \u002F 状态分层）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":403,"title":404,"meta":405},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F01-hydration-mismatch","Hydration mismatch（React \u002F Next.js）：成因、检测、排查清单与工程化规避",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":407,"title":408,"meta":409},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F01-nextjs-cache-revalidate-consistency-online-not-updating","Next.js 缓存\u002F重验证与一致性：避免「线上怎么不更新」事故（App Router）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":411,"title":412,"meta":413},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F02-csr-ssr-ssg-isr-how-to-choose","CSR vs SSR vs SSG vs ISR：怎么选？边界是什么？（体验 + 成本 + 一致性）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":415,"title":416,"meta":417},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery\u002F04-streaming-ssr-with-suspense","Streaming SSR + Suspense：提升前端感知性能的利器",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":419,"title":420,"meta":421},"\u002Fnotes\u002Freact\u002F12-rendering-and-delivery","渲染与交付（CSR\u002FSSR\u002FStreaming\u002FHydration\u002F缓存）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":423,"title":424,"meta":425},"\u002Fnotes\u002Freact\u002F13-production-readiness\u002F01-observability-logging-metrics-tracing","前端可观测性体系：日志、指标与链路追踪",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":427,"title":428,"meta":429},"\u002Fnotes\u002Freact\u002F13-production-readiness\u002F02-auth-and-web-security","鉴权与 Web 安全：OAuth, JWT, XSS, CSRF, CSP",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":431,"title":432,"meta":433},"\u002Fnotes\u002Freact\u002F13-production-readiness","生产可用性（错误\u002F可观测\u002F鉴权\u002F安全）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":435,"title":436,"meta":437},"\u002Fnotes\u002Freact\u002F14-performance\u002F01-performance-playbook-and-metrics","前端性能定位 Playbook：从指标到归因",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":439,"title":440,"meta":441},"\u002Fnotes\u002Freact\u002F14-performance\u002F02-rendering-optimization-memo-context-virtualization","React 渲染性能优化：Memo, Context, 与虚拟化",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":443,"title":444,"meta":445},"\u002Fnotes\u002Freact\u002F14-performance\u002F03-asset-and-bundle-optimization","资源与 Bundle 优化：代码分割、图片与 CDN",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":447,"title":448,"meta":449},"\u002Fnotes\u002Freact\u002F14-performance","性能体系（定位 → 优化 → 度量）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":451,"title":452,"meta":453},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F01-component-system-and-design-system","组件体系与设计系统：构建规模化前端的基石",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":455,"title":456,"meta":457},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F02-testing-strategy-rtl-e2e-testability","前端测试体系：RTL, E2E 与可测性设计",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":459,"title":460,"meta":461},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F03-monorepo-and-dependency-management","Monorepo 与依赖治理：pnpm 和 Turborepo",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":463,"title":464,"meta":465},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F04-cicd-and-quality-gates","CI\u002FCD 与质量门禁：构建可靠的自动化流程",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":467,"title":468,"meta":469},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture\u002F05-bff-and-api-design","BFF 与 API 设计：前端架构师的视角",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":471,"title":472,"meta":473},"\u002Fnotes\u002Freact\u002F15-engineering-and-architecture","工程与架构治理（规模化）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":475,"title":476,"meta":477},"\u002Fnotes\u002Freact\u002F16-advanced\u002F01-rsc-and-server-actions-deep-dive","RSC\u002FServer Actions 深水区：边界、约束与缓存一致性",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":479,"title":480,"meta":481},"\u002Fnotes\u002Freact\u002F16-advanced\u002F02-micro-frontend-governance","微前端治理：样式、路由与通信",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":483,"title":484,"meta":485},"\u002Fnotes\u002Freact\u002F16-advanced\u002F03-realtime-and-offline","实时与离线：WebSocket, PWA 与 Service Worker",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":487,"title":488,"meta":489},"\u002Fnotes\u002Freact\u002F16-advanced\u002F04-a11y-i18n-compliance","a11y, i18n 与合规：构建负责任的全球化应用",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"path":491,"title":492,"meta":493},"\u002Fnotes\u002Freact\u002F16-advanced","进阶专题（按业务需要选做）",{"date":-1,"tags":-1,"summary":-1,"lastUpdated":21},{"id":495,"type":496,"sourcePath":497,"routePath":383,"path":383,"title":384,"updatedAt":21,"meta":498,"body":500,"toc":1499},"bm90ZTpub3Rlcy9yZWFjdC8xMS1kYXRhLWxheWVyLzAxLXN0YXRlLWxheWVyaW5nLXVpLXNlcnZlci11cmwtZ2xvYmFsLm1k","note","notes\u002Freact\u002F11-data-layer\u002F01-state-layering-ui-server-url-global.md",{"id":495,"type":496,"sourcePath":497,"slug":499,"title":384,"updatedAt":21,"lastUpdated":21},"react\u002F11-data-layer\u002F01-state-layering-ui-server-url-global",{"type":501,"children":502},"root",[503,511,529,536,541,566,571,582,588,746,753,758,793,798,818,824,828,841,845,870,876,880,897,901,924,930,934,952,956,974,980,985,999,1007,1018,1026,1037,1045,1053,1066,1072,1077,1178,1183,1206,1212,1218,1265,1271,1314,1322,1328,1339,1347,1358,1366,1377,1385,1391,1445,1450,1493],{"type":504,"tag":505,"props":506,"children":508},"element","h1",{"id":507},"状态分层ui-server-url-global架构师视角",[509],{"type":510,"value":384},"text",{"type":504,"tag":512,"props":513,"children":514},"blockquote",{},[515],{"type":504,"tag":516,"props":517,"children":518},"p",{},[519,521,527],{"type":510,"value":520},"一句话结论：绝大多数 React 项目之所以“越写越乱”，根因不是缺少某个状态库，而是",{"type":504,"tag":522,"props":523,"children":524},"strong",{},[525],{"type":510,"value":526},"没有把状态按来源与生命周期分层",{"type":510,"value":528},"——把 UI state、Server state、URL state、Global state 的边界划清后，你的路由、缓存、表单、权限、性能优化都会自然收敛。",{"type":504,"tag":530,"props":531,"children":533},"h2",{"id":532},"_1-为什么要做状态分层",[534],{"type":510,"value":535},"1. 为什么要做状态分层？",{"type":504,"tag":516,"props":537,"children":538},{},[539],{"type":510,"value":540},"项目变大后，常见症状是：",{"type":504,"tag":542,"props":543,"children":544},"ul",{},[545,551,556,561],{"type":504,"tag":546,"props":547,"children":548},"li",{},[549],{"type":510,"value":550},"同一份数据同时存在于：组件 state \u002F 全局 store \u002F URL \u002F Query cache（多源真相）",{"type":504,"tag":546,"props":552,"children":553},{},[554],{"type":510,"value":555},"页面刷新、返回、分享链接后状态丢失或错乱",{"type":504,"tag":546,"props":557,"children":558},{},[559],{"type":510,"value":560},"“改一个筛选条件”导致一堆组件 re-render，但没人能解释为什么",{"type":504,"tag":546,"props":562,"children":563},{},[564],{"type":510,"value":565},"线上问题难复现：因为状态分布在各处且缺乏可观测性",{"type":504,"tag":516,"props":567,"children":568},{},[569],{"type":510,"value":570},"状态分层要解决的是一句话：",{"type":504,"tag":512,"props":572,"children":573},{},[574],{"type":504,"tag":516,"props":575,"children":576},{},[577],{"type":504,"tag":522,"props":578,"children":579},{},[580],{"type":510,"value":581},"每一类状态只允许有一个“事实来源（source of truth）”，并且明确它的生命周期与同步策略。",{"type":504,"tag":530,"props":583,"children":585},{"id":584},"_2-四类状态的定义以及最容易混的边界",[586],{"type":510,"value":587},"2. 四类状态的定义（以及最容易混的边界）",{"type":504,"tag":589,"props":590,"children":595},"pre",{"className":591,"code":592,"language":593,"meta":594,"style":594},"language-infographic shiki shiki-themes github-light github-dark","infographic list-grid-badge-card\ndata\n  title React 状态分层（四类）\n  items\n    - label UI State\n      desc 纯前端交互与展示状态（是否展开、当前 tab、输入框即时值）\n      icon mdi:gesture-tap\n    - label Server State\n      desc 来自服务端的数据及其缓存一致性（列表\u002F详情\u002F权限配置）\n      icon mdi:cloud-download\n    - label URL State\n      desc 需要“可分享\u002F可回放”的状态（筛选\u002F分页\u002F排序\u002F选中项）\n      icon mdi:link-variant\n    - label Global State\n      desc 跨页面\u002F跨模块共享且与具体路由弱相关的状态（用户会话、feature flags）\n      icon mdi:earth\n","infographic","",[596],{"type":504,"tag":597,"props":598,"children":599},"code",{"__ignoreMap":594},[600,611,620,629,638,647,656,665,674,683,692,701,710,719,728,737],{"type":504,"tag":601,"props":602,"children":605},"span",{"class":603,"line":604},"line",1,[606],{"type":504,"tag":601,"props":607,"children":608},{},[609],{"type":510,"value":610},"infographic list-grid-badge-card\n",{"type":504,"tag":601,"props":612,"children":614},{"class":603,"line":613},2,[615],{"type":504,"tag":601,"props":616,"children":617},{},[618],{"type":510,"value":619},"data\n",{"type":504,"tag":601,"props":621,"children":623},{"class":603,"line":622},3,[624],{"type":504,"tag":601,"props":625,"children":626},{},[627],{"type":510,"value":628},"  title React 状态分层（四类）\n",{"type":504,"tag":601,"props":630,"children":632},{"class":603,"line":631},4,[633],{"type":504,"tag":601,"props":634,"children":635},{},[636],{"type":510,"value":637},"  items\n",{"type":504,"tag":601,"props":639,"children":641},{"class":603,"line":640},5,[642],{"type":504,"tag":601,"props":643,"children":644},{},[645],{"type":510,"value":646},"    - label UI State\n",{"type":504,"tag":601,"props":648,"children":650},{"class":603,"line":649},6,[651],{"type":504,"tag":601,"props":652,"children":653},{},[654],{"type":510,"value":655},"      desc 纯前端交互与展示状态（是否展开、当前 tab、输入框即时值）\n",{"type":504,"tag":601,"props":657,"children":659},{"class":603,"line":658},7,[660],{"type":504,"tag":601,"props":661,"children":662},{},[663],{"type":510,"value":664},"      icon mdi:gesture-tap\n",{"type":504,"tag":601,"props":666,"children":668},{"class":603,"line":667},8,[669],{"type":504,"tag":601,"props":670,"children":671},{},[672],{"type":510,"value":673},"    - label Server State\n",{"type":504,"tag":601,"props":675,"children":677},{"class":603,"line":676},9,[678],{"type":504,"tag":601,"props":679,"children":680},{},[681],{"type":510,"value":682},"      desc 来自服务端的数据及其缓存一致性（列表\u002F详情\u002F权限配置）\n",{"type":504,"tag":601,"props":684,"children":686},{"class":603,"line":685},10,[687],{"type":504,"tag":601,"props":688,"children":689},{},[690],{"type":510,"value":691},"      icon mdi:cloud-download\n",{"type":504,"tag":601,"props":693,"children":695},{"class":603,"line":694},11,[696],{"type":504,"tag":601,"props":697,"children":698},{},[699],{"type":510,"value":700},"    - label URL State\n",{"type":504,"tag":601,"props":702,"children":704},{"class":603,"line":703},12,[705],{"type":504,"tag":601,"props":706,"children":707},{},[708],{"type":510,"value":709},"      desc 需要“可分享\u002F可回放”的状态（筛选\u002F分页\u002F排序\u002F选中项）\n",{"type":504,"tag":601,"props":711,"children":713},{"class":603,"line":712},13,[714],{"type":504,"tag":601,"props":715,"children":716},{},[717],{"type":510,"value":718},"      icon mdi:link-variant\n",{"type":504,"tag":601,"props":720,"children":722},{"class":603,"line":721},14,[723],{"type":504,"tag":601,"props":724,"children":725},{},[726],{"type":510,"value":727},"    - label Global State\n",{"type":504,"tag":601,"props":729,"children":731},{"class":603,"line":730},15,[732],{"type":504,"tag":601,"props":733,"children":734},{},[735],{"type":510,"value":736},"      desc 跨页面\u002F跨模块共享且与具体路由弱相关的状态（用户会话、feature flags）\n",{"type":504,"tag":601,"props":738,"children":740},{"class":603,"line":739},16,[741],{"type":504,"tag":601,"props":742,"children":743},{},[744],{"type":510,"value":745},"      icon mdi:earth\n",{"type":504,"tag":747,"props":748,"children":750},"h3",{"id":749},"_21-ui-state组件局部状态",[751],{"type":510,"value":752},"2.1 UI State（组件\u002F局部状态）",{"type":504,"tag":516,"props":754,"children":755},{},[756],{"type":510,"value":757},"典型例子：",{"type":504,"tag":542,"props":759,"children":760},{},[761,778,788],{"type":504,"tag":546,"props":762,"children":763},{},[764,770,772],{"type":504,"tag":597,"props":765,"children":767},{"className":766},[],[768],{"type":510,"value":769},"isOpen",{"type":510,"value":771}," \u002F ",{"type":504,"tag":597,"props":773,"children":775},{"className":774},[],[776],{"type":510,"value":777},"activeTab",{"type":504,"tag":546,"props":779,"children":780},{},[781,783],{"type":510,"value":782},"输入框即时值 ",{"type":504,"tag":597,"props":784,"children":786},{"className":785},[],[787],{"type":510,"value":510},{"type":504,"tag":546,"props":789,"children":790},{},[791],{"type":510,"value":792},"hover\u002Ffocus、modal 打开状态",{"type":504,"tag":516,"props":794,"children":795},{},[796],{"type":510,"value":797},"特征：",{"type":504,"tag":542,"props":799,"children":800},{},[801,806],{"type":504,"tag":546,"props":802,"children":803},{},[804],{"type":510,"value":805},"生命周期短，通常不需要跨页面持久化",{"type":504,"tag":546,"props":807,"children":808},{},[809,811,816],{"type":510,"value":810},"频繁变化，",{"type":504,"tag":522,"props":812,"children":813},{},[814],{"type":510,"value":815},"越靠近组件越好",{"type":510,"value":817},"（避免全局更新导致无谓渲染）",{"type":504,"tag":747,"props":819,"children":821},{"id":820},"_22-server-state服务端数据状态",[822],{"type":510,"value":823},"2.2 Server State（服务端数据状态）",{"type":504,"tag":516,"props":825,"children":826},{},[827],{"type":510,"value":757},{"type":504,"tag":542,"props":829,"children":830},{},[831,836],{"type":504,"tag":546,"props":832,"children":833},{},[834],{"type":510,"value":835},"列表\u002F详情数据",{"type":504,"tag":546,"props":837,"children":838},{},[839],{"type":510,"value":840},"用户权限列表、配置下发",{"type":504,"tag":516,"props":842,"children":843},{},[844],{"type":510,"value":797},{"type":504,"tag":542,"props":846,"children":847},{},[848,853,858],{"type":504,"tag":546,"props":849,"children":850},{},[851],{"type":510,"value":852},"真相在服务端",{"type":504,"tag":546,"props":854,"children":855},{},[856],{"type":510,"value":857},"需要缓存、去重、失效、重试、分页、预取",{"type":504,"tag":546,"props":859,"children":860},{},[861,863,868],{"type":510,"value":862},"最佳实践通常是：",{"type":504,"tag":522,"props":864,"children":865},{},[866],{"type":510,"value":867},"用专门的 Server State 库管理",{"type":510,"value":869},"（TanStack Query \u002F SWR 等），而不是塞进全局 store",{"type":504,"tag":747,"props":871,"children":873},{"id":872},"_23-url-state路由可回放状态",[874],{"type":510,"value":875},"2.3 URL State（路由可回放状态）",{"type":504,"tag":516,"props":877,"children":878},{},[879],{"type":510,"value":757},{"type":504,"tag":542,"props":881,"children":882},{},[883,892],{"type":504,"tag":546,"props":884,"children":885},{},[886],{"type":504,"tag":597,"props":887,"children":889},{"className":888},[],[890],{"type":510,"value":891},"?keyword=...&page=2&sort=price_desc",{"type":504,"tag":546,"props":893,"children":894},{},[895],{"type":510,"value":896},"选中的 itemId",{"type":504,"tag":516,"props":898,"children":899},{},[900],{"type":510,"value":797},{"type":504,"tag":542,"props":902,"children":903},{},[904,909,914],{"type":504,"tag":546,"props":905,"children":906},{},[907],{"type":510,"value":908},"需要可分享（复制链接给别人应还原视图）",{"type":504,"tag":546,"props":910,"children":911},{},[912],{"type":510,"value":913},"需要可回退（浏览器 back\u002Fforward 应还原视图）",{"type":504,"tag":546,"props":915,"children":916},{},[917,919],{"type":510,"value":918},"一般和路由强绑定：",{"type":504,"tag":522,"props":920,"children":921},{},[922],{"type":510,"value":923},"适合由路由层（TanStack Router \u002F Next App Router）管理",{"type":504,"tag":747,"props":925,"children":927},{"id":926},"_24-global-state跨路由共享状态",[928],{"type":510,"value":929},"2.4 Global State（跨路由共享状态）",{"type":504,"tag":516,"props":931,"children":932},{},[933],{"type":510,"value":757},{"type":504,"tag":542,"props":935,"children":936},{},[937,942,947],{"type":504,"tag":546,"props":938,"children":939},{},[940],{"type":510,"value":941},"登录会话（user\u002Fsession）",{"type":504,"tag":546,"props":943,"children":944},{},[945],{"type":510,"value":946},"feature flags \u002F AB 实验开关",{"type":504,"tag":546,"props":948,"children":949},{},[950],{"type":510,"value":951},"全局主题\u002F语言",{"type":504,"tag":516,"props":953,"children":954},{},[955],{"type":510,"value":797},{"type":504,"tag":542,"props":957,"children":958},{},[959,964,969],{"type":504,"tag":546,"props":960,"children":961},{},[962],{"type":510,"value":963},"跨页面共享",{"type":504,"tag":546,"props":965,"children":966},{},[967],{"type":510,"value":968},"变化频率通常低（否则会导致大面积 re-render）",{"type":504,"tag":546,"props":970,"children":971},{},[972],{"type":510,"value":973},"需要良好的“订阅粒度”（selector）与模块边界",{"type":504,"tag":530,"props":975,"children":977},{"id":976},"_3-一个可执行的决策流程放置原则",[978],{"type":510,"value":979},"3. 一个可执行的决策流程（放置原则）",{"type":504,"tag":516,"props":981,"children":982},{},[983],{"type":510,"value":984},"当你遇到一个“需要状态”的需求时，按下面顺序问：",{"type":504,"tag":986,"props":987,"children":988},"ol",{},[989],{"type":504,"tag":546,"props":990,"children":991},{},[992,997],{"type":504,"tag":522,"props":993,"children":994},{},[995],{"type":510,"value":996},"它是否必须出现在 URL 里？",{"type":510,"value":998},"（可分享\u002F可回放\u002F可回退）",{"type":504,"tag":542,"props":1000,"children":1001},{},[1002],{"type":504,"tag":546,"props":1003,"children":1004},{},[1005],{"type":510,"value":1006},"是 → URL State（路由）",{"type":504,"tag":986,"props":1008,"children":1009},{"start":613},[1010],{"type":504,"tag":546,"props":1011,"children":1012},{},[1013],{"type":504,"tag":522,"props":1014,"children":1015},{},[1016],{"type":510,"value":1017},"它是否来自服务端，并需要缓存一致性？",{"type":504,"tag":542,"props":1019,"children":1020},{},[1021],{"type":504,"tag":546,"props":1022,"children":1023},{},[1024],{"type":510,"value":1025},"是 → Server State（Query cache）",{"type":504,"tag":986,"props":1027,"children":1028},{"start":622},[1029],{"type":504,"tag":546,"props":1030,"children":1031},{},[1032],{"type":504,"tag":522,"props":1033,"children":1034},{},[1035],{"type":510,"value":1036},"它是否跨路由共享，且与具体页面弱绑定？",{"type":504,"tag":542,"props":1038,"children":1039},{},[1040],{"type":504,"tag":546,"props":1041,"children":1042},{},[1043],{"type":510,"value":1044},"是 → Global State（store\u002Fcontext）",{"type":504,"tag":986,"props":1046,"children":1047},{"start":631},[1048],{"type":504,"tag":546,"props":1049,"children":1050},{},[1051],{"type":510,"value":1052},"否则 → UI State（组件\u002F局部）",{"type":504,"tag":512,"props":1054,"children":1055},{},[1056],{"type":504,"tag":516,"props":1057,"children":1058},{},[1059,1061],{"type":510,"value":1060},"这套流程的核心是：",{"type":504,"tag":522,"props":1062,"children":1063},{},[1064],{"type":510,"value":1065},"尽量不要“为了方便”把东西放进全局 store。",{"type":504,"tag":530,"props":1067,"children":1069},{"id":1068},"_4-典型业务案例搜索列表页推荐拆法",[1070],{"type":510,"value":1071},"4. 典型业务案例：搜索列表页（推荐拆法）",{"type":504,"tag":516,"props":1073,"children":1074},{},[1075],{"type":510,"value":1076},"以“商品搜索列表”为例：",{"type":504,"tag":542,"props":1078,"children":1079},{},[1080,1110,1129,1148],{"type":504,"tag":546,"props":1081,"children":1082},{},[1083,1085],{"type":510,"value":1084},"UI State",{"type":504,"tag":542,"props":1086,"children":1087},{},[1088,1099],{"type":504,"tag":546,"props":1089,"children":1090},{},[1091,1092,1097],{"type":510,"value":782},{"type":504,"tag":597,"props":1093,"children":1095},{"className":1094},[],[1096],{"type":510,"value":510},{"type":510,"value":1098},"（为了输入流畅，甚至可与 Transition 配合）",{"type":504,"tag":546,"props":1100,"children":1101},{},[1102,1104],{"type":510,"value":1103},"侧边栏展开\u002F收起 ",{"type":504,"tag":597,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":510,"value":1109},"isFilterOpen",{"type":504,"tag":546,"props":1111,"children":1112},{},[1113,1115],{"type":510,"value":1114},"URL State",{"type":504,"tag":542,"props":1116,"children":1117},{},[1118],{"type":504,"tag":546,"props":1119,"children":1120},{},[1121,1127],{"type":504,"tag":597,"props":1122,"children":1124},{"className":1123},[],[1125],{"type":510,"value":1126},"keyword\u002Fpage\u002Fsort\u002Ffilters",{"type":510,"value":1128},"（必须可分享、可回退）",{"type":504,"tag":546,"props":1130,"children":1131},{},[1132,1134],{"type":510,"value":1133},"Server State",{"type":504,"tag":542,"props":1135,"children":1136},{},[1137],{"type":504,"tag":546,"props":1138,"children":1139},{},[1140,1146],{"type":504,"tag":597,"props":1141,"children":1143},{"className":1142},[],[1144],{"type":510,"value":1145},"products",{"type":510,"value":1147}," 列表数据（由 URL state 派生出来的查询条件驱动）",{"type":504,"tag":546,"props":1149,"children":1150},{},[1151,1153],{"type":510,"value":1152},"Global State",{"type":504,"tag":542,"props":1154,"children":1155},{},[1156,1167],{"type":504,"tag":546,"props":1157,"children":1158},{},[1159,1165],{"type":504,"tag":597,"props":1160,"children":1162},{"className":1161},[],[1163],{"type":510,"value":1164},"session\u002Fuser",{"type":510,"value":1166},"（用户信息、登录态）",{"type":504,"tag":546,"props":1168,"children":1169},{},[1170,1176],{"type":504,"tag":597,"props":1171,"children":1173},{"className":1172},[],[1174],{"type":510,"value":1175},"featureFlags",{"type":510,"value":1177},"（实验开关）",{"type":504,"tag":516,"props":1179,"children":1180},{},[1181],{"type":510,"value":1182},"关键约束：",{"type":504,"tag":542,"props":1184,"children":1185},{},[1186,1196],{"type":504,"tag":546,"props":1187,"children":1188},{},[1189,1194],{"type":504,"tag":522,"props":1190,"children":1191},{},[1192],{"type":510,"value":1193},"查询条件的单一真相在 URL",{"type":510,"value":1195},"（不是 store、不是组件 state）",{"type":504,"tag":546,"props":1197,"children":1198},{},[1199,1204],{"type":504,"tag":522,"props":1200,"children":1201},{},[1202],{"type":510,"value":1203},"数据的单一真相在 Query cache",{"type":510,"value":1205},"（不是 store）",{"type":504,"tag":530,"props":1207,"children":1209},{"id":1208},"_5-两套技术栈下的落地方式",[1210],{"type":510,"value":1211},"5. 两套技术栈下的落地方式",{"type":504,"tag":747,"props":1213,"children":1215},{"id":1214},"_51-tanstack-router-vite",[1216],{"type":510,"value":1217},"5.1 TanStack Router + Vite",{"type":504,"tag":542,"props":1219,"children":1220},{},[1221,1247],{"type":504,"tag":546,"props":1222,"children":1223},{},[1224,1226],{"type":510,"value":1225},"URL State：",{"type":504,"tag":542,"props":1227,"children":1228},{},[1229,1242],{"type":504,"tag":546,"props":1230,"children":1231},{},[1232,1234,1240],{"type":510,"value":1233},"用 TanStack Router 的 ",{"type":504,"tag":597,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":510,"value":1239},"search params",{"type":510,"value":1241}," 作为 query 条件",{"type":504,"tag":546,"props":1243,"children":1244},{},[1245],{"type":510,"value":1246},"通过 schema 校验\u002F默认值确保“链接可还原”",{"type":504,"tag":546,"props":1248,"children":1249},{},[1250,1252],{"type":510,"value":1251},"Server State：",{"type":504,"tag":542,"props":1253,"children":1254},{},[1255,1260],{"type":504,"tag":546,"props":1256,"children":1257},{},[1258],{"type":510,"value":1259},"用 TanStack Query 管理",{"type":504,"tag":546,"props":1261,"children":1262},{},[1263],{"type":510,"value":1264},"可以在 route loader 里 prefetch（让导航更快）",{"type":504,"tag":747,"props":1266,"children":1268},{"id":1267},"_52-nextjs-app-router",[1269],{"type":510,"value":1270},"5.2 Next.js App Router",{"type":504,"tag":542,"props":1272,"children":1273},{},[1274,1297],{"type":504,"tag":546,"props":1275,"children":1276},{},[1277,1278],{"type":510,"value":1225},{"type":504,"tag":542,"props":1279,"children":1280},{},[1281,1292],{"type":504,"tag":546,"props":1282,"children":1283},{},[1284,1290],{"type":504,"tag":597,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":510,"value":1289},"searchParams",{"type":510,"value":1291}," 是天然的 URL state",{"type":504,"tag":546,"props":1293,"children":1294},{},[1295],{"type":510,"value":1296},"适合把筛选\u002F分页做成可分享链接",{"type":504,"tag":546,"props":1298,"children":1299},{},[1300,1301],{"type":510,"value":1251},{"type":504,"tag":542,"props":1302,"children":1303},{},[1304,1309],{"type":504,"tag":546,"props":1305,"children":1306},{},[1307],{"type":510,"value":1308},"如果数据在 Server Components 获取：它更像“框架级 Server State + 缓存”（与 Next 缓存\u002F重验证绑定）",{"type":504,"tag":546,"props":1310,"children":1311},{},[1312],{"type":510,"value":1313},"如果数据在 Client Components 获取：仍建议用 TanStack Query 管理缓存一致性",{"type":504,"tag":512,"props":1315,"children":1316},{},[1317],{"type":504,"tag":516,"props":1318,"children":1319},{},[1320],{"type":510,"value":1321},"架构建议：不要在同一个数据域里混用多套“真相来源”。",{"type":504,"tag":530,"props":1323,"children":1325},{"id":1324},"_6-常见反模式踩一次就会懂",[1326],{"type":510,"value":1327},"6. 常见反模式（踩一次就会懂）",{"type":504,"tag":986,"props":1329,"children":1330},{},[1331],{"type":504,"tag":546,"props":1332,"children":1333},{},[1334],{"type":504,"tag":522,"props":1335,"children":1336},{},[1337],{"type":510,"value":1338},"把 URL state 复制一份到 store",{"type":504,"tag":542,"props":1340,"children":1341},{},[1342],{"type":504,"tag":546,"props":1343,"children":1344},{},[1345],{"type":510,"value":1346},"后果：back\u002Fforward 不可回放；分享链接不一致；两处同步复杂",{"type":504,"tag":986,"props":1348,"children":1349},{"start":613},[1350],{"type":504,"tag":546,"props":1351,"children":1352},{},[1353],{"type":504,"tag":522,"props":1354,"children":1355},{},[1356],{"type":510,"value":1357},"把 Server state 塞进全局 store",{"type":504,"tag":542,"props":1359,"children":1360},{},[1361],{"type":504,"tag":546,"props":1362,"children":1363},{},[1364],{"type":510,"value":1365},"后果：你要自己实现缓存、失效、去重、重试、分页…最后重复造 TanStack Query",{"type":504,"tag":986,"props":1367,"children":1368},{"start":622},[1369],{"type":504,"tag":546,"props":1370,"children":1371},{},[1372],{"type":504,"tag":522,"props":1373,"children":1374},{},[1375],{"type":510,"value":1376},"把高频 UI state 放全局",{"type":504,"tag":542,"props":1378,"children":1379},{},[1380],{"type":504,"tag":546,"props":1381,"children":1382},{},[1383],{"type":510,"value":1384},"后果：每次输入导致全局订阅者 re-render，性能灾难",{"type":504,"tag":530,"props":1386,"children":1388},{"id":1387},"_7-checklist",[1389],{"type":510,"value":1390},"7. Checklist",{"type":504,"tag":542,"props":1392,"children":1395},{"className":1393},[1394],"contains-task-list",[1396,1409,1418,1427,1436],{"type":504,"tag":546,"props":1397,"children":1400},{"className":1398},[1399],"task-list-item",[1401,1407],{"type":504,"tag":1402,"props":1403,"children":1406},"input",{"disabled":1404,"type":1405},true,"checkbox",[],{"type":510,"value":1408}," 这个状态的 source of truth 是什么？（只能有一个）",{"type":504,"tag":546,"props":1410,"children":1412},{"className":1411},[1399],[1413,1416],{"type":504,"tag":1402,"props":1414,"children":1415},{"disabled":1404,"type":1405},[],{"type":510,"value":1417}," 它是否必须可分享\u002F可回放？如果是，是否进 URL？",{"type":504,"tag":546,"props":1419,"children":1421},{"className":1420},[1399],[1422,1425],{"type":504,"tag":1402,"props":1423,"children":1424},{"disabled":1404,"type":1405},[],{"type":510,"value":1426}," 它是否来自服务端并需要缓存一致性？如果是，是否交给 Query？",{"type":504,"tag":546,"props":1428,"children":1430},{"className":1429},[1399],[1431,1434],{"type":504,"tag":1402,"props":1432,"children":1433},{"disabled":1404,"type":1405},[],{"type":510,"value":1435}," 它是否跨路由共享？如果是，Global state 的订阅粒度是否足够细？",{"type":504,"tag":546,"props":1437,"children":1439},{"className":1438},[1399],[1440,1443],{"type":504,"tag":1402,"props":1441,"children":1442},{"disabled":1404,"type":1405},[],{"type":510,"value":1444}," 是否存在同一数据域的“多源真相”？（最危险）",{"type":504,"tag":530,"props":1446,"children":1448},{"id":1447},"关联阅读",[1449],{"type":510,"value":1447},{"type":504,"tag":542,"props":1451,"children":1452},{},[1453,1464,1479],{"type":504,"tag":546,"props":1454,"children":1455},{},[1456,1458],{"type":510,"value":1457},"TanStack Query 缓存与失效（下一篇）：",{"type":504,"tag":597,"props":1459,"children":1461},{"className":1460},[],[1462],{"type":510,"value":1463},".\u002F02-tanstack-query-caching-and-invalidation.md",{"type":504,"tag":546,"props":1465,"children":1466},{},[1467,1469],{"type":510,"value":1468},"路由与 URL state（章节）：",{"type":504,"tag":1470,"props":1471,"children":1473},"a",{"href":1472},"..\u002F10-routing-and-navigation\u002FREADME.md",[1474],{"type":504,"tag":597,"props":1475,"children":1477},{"className":1476},[],[1478],{"type":510,"value":1472},{"type":504,"tag":546,"props":1480,"children":1481},{},[1482,1484],{"type":510,"value":1483},"React 18 Transition（输入与结果区拆分）：",{"type":504,"tag":1470,"props":1485,"children":1487},{"href":1486},"..\u002F09-react-18-in-practice\u002F03-transition-useTransition-useDeferredValue.md",[1488],{"type":504,"tag":597,"props":1489,"children":1491},{"className":1490},[],[1492],{"type":510,"value":1486},{"type":504,"tag":1494,"props":1495,"children":1496},"style",{},[1497],{"type":510,"value":1498},"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);}",{"title":594,"searchDepth":613,"depth":613,"links":1500},[1501,1502,1508,1509,1510,1514,1515,1516],{"id":532,"depth":613,"text":535},{"id":584,"depth":613,"text":587,"children":1503},[1504,1505,1506,1507],{"id":749,"depth":622,"text":752},{"id":820,"depth":622,"text":823},{"id":872,"depth":622,"text":875},{"id":926,"depth":622,"text":929},{"id":976,"depth":613,"text":979},{"id":1068,"depth":613,"text":1071},{"id":1208,"depth":613,"text":1211,"children":1511},[1512,1513],{"id":1214,"depth":622,"text":1217},{"id":1267,"depth":622,"text":1270},{"id":1324,"depth":613,"text":1327},{"id":1387,"depth":613,"text":1390},{"id":1447,"depth":613,"text":1447},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1518},"\u003Cpath fill=\"currentColor\" d=\"m10.828 12l4.95 4.95l-1.414 1.415L8 12l6.364-6.364l1.414 1.414z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1520},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm0 7h12v2H3zm0 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1522},"\u003Cpath fill=\"currentColor\" d=\"m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z\"\u002F>",{"left":4,"top":4,"width":1524,"height":1524,"rotate":4,"vFlip":6,"hFlip":6,"body":1525},1024,"\u003Cpath fill=\"currentColor\" d=\"M768 832a128 128 0 0 1-128 128H192A128 128 0 0 1 64 832V384a128 128 0 0 1 128-128v64a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64z\"\u002F>\u003Cpath fill=\"currentColor\" d=\"M384 128a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64V192a64 64 0 0 0-64-64zm0-64h448a128 128 0 0 1 128 128v448a128 128 0 0 1-128 128H384a128 128 0 0 1-128-128V192A128 128 0 0 1 384 64\"\u002F>"]