[{"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-16-advanced\u002F01-rsc-and-server-actions-deep-dive":494,"i-ri:arrow-left-s-line":1852,"i-ri:menu-2-line":1854,"i-ri:arrow-right-s-line":1856,"i-ep:copy-document":1858},{"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":475,"path":475,"title":476,"updatedAt":21,"meta":498,"body":500,"toc":1835},"bm90ZTpub3Rlcy9yZWFjdC8xNi1hZHZhbmNlZC8wMS1yc2MtYW5kLXNlcnZlci1hY3Rpb25zLWRlZXAtZGl2ZS5tZA","note","notes\u002Freact\u002F16-advanced\u002F01-rsc-and-server-actions-deep-dive.md",{"id":495,"type":496,"sourcePath":497,"slug":499,"title":476,"updatedAt":21,"lastUpdated":21},"react\u002F16-advanced\u002F01-rsc-and-server-actions-deep-dive",{"type":501,"children":502},"root",[503,511,527,531,538,543,710,713,719,724,737,838,850,872,878,883,1424,1427,1433,1439,1515,1521,1526,1628,1634,1669,1699,1702,1708,1770,1775,1778,1784,1829],{"type":504,"tag":505,"props":506,"children":508},"element","h1",{"id":507},"rscserver-actions-深水区边界约束与缓存一致性",[509],{"type":510,"value":476},"text",{"type":504,"tag":512,"props":513,"children":514},"blockquote",{},[515],{"type":504,"tag":516,"props":517,"children":518},"p",{},[519,525],{"type":504,"tag":520,"props":521,"children":522},"strong",{},[523],{"type":510,"value":524},"一句话结论",{"type":510,"value":526},"：React Server Components (RSC) 和 Server Actions 通过将组件渲染和数据变更的重心移回服务器，实现了零 Bundle 体积的组件和原生的 RPC 调用，但也引入了关于“客户端-服务器”边界、状态管理、缓存失效等一系列全新的心智模型和工程挑战。",{"type":504,"tag":528,"props":529,"children":530},"hr",{},[],{"type":504,"tag":532,"props":533,"children":535},"h2",{"id":534},"_1-核心概念回顾",[536],{"type":510,"value":537},"1. 核心概念回顾",{"type":504,"tag":516,"props":539,"children":540},{},[541],{"type":510,"value":542},"在深入“深水区”之前，我们必须清晰地理解这两个概念。",{"type":504,"tag":544,"props":545,"children":546},"ul",{},[547,640],{"type":504,"tag":548,"props":549,"children":550},"li",{},[551,556,558],{"type":504,"tag":520,"props":552,"children":553},{},[554],{"type":510,"value":555},"React Server Components (RSC)",{"type":510,"value":557},"：",{"type":504,"tag":544,"props":559,"children":560},{},[561,585,595,630],{"type":504,"tag":548,"props":562,"children":563},{},[564,569,571,576,578,583],{"type":504,"tag":520,"props":565,"children":566},{},[567],{"type":510,"value":568},"定义",{"type":510,"value":570},"：在服务器上",{"type":504,"tag":520,"props":572,"children":573},{},[574],{"type":510,"value":575},"专门为 React",{"type":510,"value":577}," 渲染的组件。它们的",{"type":504,"tag":520,"props":579,"children":580},{},[581],{"type":510,"value":582},"代码永不进入客户端 JS bundle",{"type":510,"value":584},"。",{"type":504,"tag":548,"props":586,"children":587},{},[588,593],{"type":504,"tag":520,"props":589,"children":590},{},[591],{"type":510,"value":592},"输出",{"type":510,"value":594},"：不是 HTML，而是一种特殊的、可流式传输的虚拟 DOM 描述格式。",{"type":504,"tag":548,"props":596,"children":597},{},[598,603,605,612,614,620,622,628],{"type":504,"tag":520,"props":599,"children":600},{},[601],{"type":510,"value":602},"能力",{"type":510,"value":604},"：可以直接访问服务器资源（数据库、文件系统、内部 API）；可以使用 ",{"type":504,"tag":606,"props":607,"children":609},"code",{"className":608},[],[610],{"type":510,"value":611},"async\u002Fawait",{"type":510,"value":613},"；不能使用任何客户端交互能力（",{"type":504,"tag":606,"props":615,"children":617},{"className":616},[],[618],{"type":510,"value":619},"useState",{"type":510,"value":621},", ",{"type":504,"tag":606,"props":623,"children":625},{"className":624},[],[626],{"type":510,"value":627},"useEffect",{"type":510,"value":629},", 事件监听器）。",{"type":504,"tag":548,"props":631,"children":632},{},[633,638],{"type":504,"tag":520,"props":634,"children":635},{},[636],{"type":510,"value":637},"目标",{"type":510,"value":639},"：将非交互、数据密集型的 UI 渲染成本从客户端剥离。",{"type":504,"tag":548,"props":641,"children":642},{},[643,648,649],{"type":504,"tag":520,"props":644,"children":645},{},[646],{"type":510,"value":647},"Server Actions",{"type":510,"value":557},{"type":504,"tag":544,"props":650,"children":651},{},[652,668,693],{"type":504,"tag":548,"props":653,"children":654},{},[655,659,661,666],{"type":504,"tag":520,"props":656,"children":657},{},[658],{"type":510,"value":568},{"type":510,"value":660},"：在服务器上定义，但可以被客户端组件",{"type":504,"tag":520,"props":662,"children":663},{},[664],{"type":510,"value":665},"直接调用",{"type":510,"value":667},"的函数。这是一个内置于 React 的 RPC (Remote Procedure Call) 机制。",{"type":504,"tag":548,"props":669,"children":670},{},[671,675,677,683,685,691],{"type":504,"tag":520,"props":672,"children":673},{},[674],{"type":510,"value":602},{"type":510,"value":676},"：可以安全地执行数据库变更、API 调用等服务器端操作。与 ",{"type":504,"tag":606,"props":678,"children":680},{"className":679},[],[681],{"type":510,"value":682},"form",{"type":510,"value":684}," 标签原生集成，并可通过 ",{"type":504,"tag":606,"props":686,"children":688},{"className":687},[],[689],{"type":510,"value":690},"startTransition",{"type":510,"value":692}," 调用。",{"type":504,"tag":548,"props":694,"children":695},{},[696,700,702,708],{"type":504,"tag":520,"props":697,"children":698},{},[699],{"type":510,"value":637},{"type":510,"value":701},"：简化客户端的数据变更（mutations）逻辑，无需再手动编写 API 端点、",{"type":504,"tag":606,"props":703,"children":705},{"className":704},[],[706],{"type":510,"value":707},"fetch",{"type":510,"value":709}," 调用和状态管理。",{"type":504,"tag":528,"props":711,"children":712},{},[],{"type":504,"tag":532,"props":714,"children":716},{"id":715},"_2-use-client-与-use-server边界的守门人",[717],{"type":510,"value":718},"2. “use client” 与 “use server”：边界的守门人",{"type":504,"tag":516,"props":720,"children":721},{},[722],{"type":510,"value":723},"这是理解 RSC 体系最核心、也最容易混淆的概念。这两个指令定义了客户端与服务器代码的边界。",{"type":504,"tag":725,"props":726,"children":728},"h3",{"id":727},"a-use-client",[729,731],{"type":510,"value":730},"A. ",{"type":504,"tag":606,"props":732,"children":734},{"className":733},[],[735],{"type":510,"value":736},"'use client'",{"type":504,"tag":544,"props":738,"children":739},{},[740,755,779,808],{"type":504,"tag":548,"props":741,"children":742},{},[743,747,749,754],{"type":504,"tag":520,"props":744,"children":745},{},[746],{"type":510,"value":568},{"type":510,"value":748},"：一个文件顶部的指令，它声明该文件及其导入的所有模块都是",{"type":504,"tag":520,"props":750,"children":751},{},[752],{"type":510,"value":753},"客户端组件 (Client Components)",{"type":510,"value":584},{"type":504,"tag":548,"props":756,"children":757},{},[758,763,765,770,772,777],{"type":504,"tag":520,"props":759,"children":760},{},[761],{"type":510,"value":762},"传染性",{"type":510,"value":764},"：一旦一个文件被标记为 ",{"type":504,"tag":606,"props":766,"children":768},{"className":767},[],[769],{"type":510,"value":736},{"type":510,"value":771},"，所有被它导入的文件，无论其内容如何，都会被打包到客户端 JS bundle 中。这是 ",{"type":504,"tag":606,"props":773,"children":775},{"className":774},[],[776],{"type":510,"value":736},{"type":510,"value":778}," 的“传染性”。",{"type":504,"tag":548,"props":780,"children":781},{},[782,786,788,793,794,799,800,806],{"type":504,"tag":520,"props":783,"children":784},{},[785],{"type":510,"value":602},{"type":510,"value":787},"：可以使用 ",{"type":504,"tag":606,"props":789,"children":791},{"className":790},[],[792],{"type":510,"value":619},{"type":510,"value":621},{"type":504,"tag":606,"props":795,"children":797},{"className":796},[],[798],{"type":510,"value":627},{"type":510,"value":621},{"type":504,"tag":606,"props":801,"children":803},{"className":802},[],[804],{"type":510,"value":805},"onClick",{"type":510,"value":807}," 等所有传统 React 的能力。",{"type":504,"tag":548,"props":809,"children":810},{},[811,816,817,822,824,829,831,836],{"type":504,"tag":520,"props":812,"children":813},{},[814],{"type":510,"value":815},"误区",{"type":510,"value":557},{"type":504,"tag":606,"props":818,"children":820},{"className":819},[],[821],{"type":510,"value":736},{"type":510,"value":823}," ",{"type":504,"tag":520,"props":825,"children":826},{},[827],{"type":510,"value":828},"不代表“只在客户端渲染”",{"type":510,"value":830},"。在 Next.js 等框架中，客户端组件默认也会在服务器进行首次渲染 (SSR)，然后发送到客户端进行 Hydration。它真正的意思是：“这个组件的 JS 代码",{"type":504,"tag":520,"props":832,"children":833},{},[834],{"type":510,"value":835},"需要",{"type":510,"value":837},"被发送到客户端，以使其具备交互性”。",{"type":504,"tag":725,"props":839,"children":841},{"id":840},"b-use-server",[842,844],{"type":510,"value":843},"B. ",{"type":504,"tag":606,"props":845,"children":847},{"className":846},[],[848],{"type":510,"value":849},"'use server'",{"type":504,"tag":544,"props":851,"children":852},{},[853,862],{"type":504,"tag":548,"props":854,"children":855},{},[856,860],{"type":504,"tag":520,"props":857,"children":858},{},[859],{"type":510,"value":568},{"type":510,"value":861},"：一个文件或函数顶部的指令，它声明该文件中的所有导出函数（或单个函数）是 Server Actions，可以被客户端安全地调用。",{"type":504,"tag":548,"props":863,"children":864},{},[865,870],{"type":504,"tag":520,"props":866,"children":867},{},[868],{"type":510,"value":869},"工作原理",{"type":510,"value":871},"：编译器会创建一个指向该服务器函数的引用（可以理解为一个特殊的 URL 端点），并将其作为 prop 传递给客户端组件。当客户端调用这个“函数”时，React 在底层发起一个到该端点的 POST 请求。",{"type":504,"tag":725,"props":873,"children":875},{"id":874},"c-组件的跨界组合",[876],{"type":510,"value":877},"C. 组件的“跨界”组合",{"type":504,"tag":516,"props":879,"children":880},{},[881],{"type":510,"value":882},"RSC 和客户端组件可以相互嵌套，但这有严格的规则：",{"type":504,"tag":884,"props":885,"children":886},"ol",{},[887,1039,1173],{"type":504,"tag":548,"props":888,"children":889},{},[890,895,896],{"type":504,"tag":520,"props":891,"children":892},{},[893],{"type":510,"value":894},"Server Components 可以直接导入并渲染 Client Components",{"type":510,"value":584},{"type":504,"tag":897,"props":898,"children":903},"pre",{"className":899,"code":900,"language":901,"meta":902,"style":902},"language-jsx shiki shiki-themes github-light github-dark","\u002F\u002F server-component.js (RSC, by default)\nimport ClientButton from '.\u002Fclient-button'; \u002F\u002F client-button.js has 'use client'\n\nexport default function ServerPage() {\n  \u002F\u002F ✅ OK\n  return \u003CClientButton \u002F>;\n}\n","jsx","",[904],{"type":504,"tag":606,"props":905,"children":906},{"__ignoreMap":902},[907,919,956,966,996,1005,1030],{"type":504,"tag":908,"props":909,"children":912},"span",{"class":910,"line":911},"line",1,[913],{"type":504,"tag":908,"props":914,"children":916},{"style":915},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[917],{"type":510,"value":918},"\u002F\u002F server-component.js (RSC, by default)\n",{"type":504,"tag":908,"props":920,"children":922},{"class":910,"line":921},2,[923,929,935,940,946,951],{"type":504,"tag":908,"props":924,"children":926},{"style":925},"--shiki-default:#D73A49;--shiki-dark:#F97583",[927],{"type":510,"value":928},"import",{"type":504,"tag":908,"props":930,"children":932},{"style":931},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[933],{"type":510,"value":934}," ClientButton ",{"type":504,"tag":908,"props":936,"children":937},{"style":925},[938],{"type":510,"value":939},"from",{"type":504,"tag":908,"props":941,"children":943},{"style":942},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[944],{"type":510,"value":945}," '.\u002Fclient-button'",{"type":504,"tag":908,"props":947,"children":948},{"style":931},[949],{"type":510,"value":950},"; ",{"type":504,"tag":908,"props":952,"children":953},{"style":915},[954],{"type":510,"value":955},"\u002F\u002F client-button.js has 'use client'\n",{"type":504,"tag":908,"props":957,"children":959},{"class":910,"line":958},3,[960],{"type":504,"tag":908,"props":961,"children":963},{"emptyLinePlaceholder":962},true,[964],{"type":510,"value":965},"\n",{"type":504,"tag":908,"props":967,"children":969},{"class":910,"line":968},4,[970,975,980,985,991],{"type":504,"tag":908,"props":971,"children":972},{"style":925},[973],{"type":510,"value":974},"export",{"type":504,"tag":908,"props":976,"children":977},{"style":925},[978],{"type":510,"value":979}," default",{"type":504,"tag":908,"props":981,"children":982},{"style":925},[983],{"type":510,"value":984}," function",{"type":504,"tag":908,"props":986,"children":988},{"style":987},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[989],{"type":510,"value":990}," ServerPage",{"type":504,"tag":908,"props":992,"children":993},{"style":931},[994],{"type":510,"value":995},"() {\n",{"type":504,"tag":908,"props":997,"children":999},{"class":910,"line":998},5,[1000],{"type":504,"tag":908,"props":1001,"children":1002},{"style":915},[1003],{"type":510,"value":1004},"  \u002F\u002F ✅ OK\n",{"type":504,"tag":908,"props":1006,"children":1008},{"class":910,"line":1007},6,[1009,1014,1019,1025],{"type":504,"tag":908,"props":1010,"children":1011},{"style":925},[1012],{"type":510,"value":1013},"  return",{"type":504,"tag":908,"props":1015,"children":1016},{"style":931},[1017],{"type":510,"value":1018}," \u003C",{"type":504,"tag":908,"props":1020,"children":1022},{"style":1021},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[1023],{"type":510,"value":1024},"ClientButton",{"type":504,"tag":908,"props":1026,"children":1027},{"style":931},[1028],{"type":510,"value":1029}," \u002F>;\n",{"type":504,"tag":908,"props":1031,"children":1033},{"class":910,"line":1032},7,[1034],{"type":504,"tag":908,"props":1035,"children":1036},{"style":931},[1037],{"type":510,"value":1038},"}\n",{"type":504,"tag":548,"props":1040,"children":1041},{},[1042,1047,1049],{"type":504,"tag":520,"props":1043,"children":1044},{},[1045],{"type":510,"value":1046},"Client Components 不能直接导入并渲染 Server Components",{"type":510,"value":1048},"。（因为 RSC 需要在服务器上运行，而客户端不知道如何执行它）。",{"type":504,"tag":897,"props":1050,"children":1052},{"className":899,"code":1051,"language":901,"meta":902,"style":902},"\u002F\u002F client-component.js\n'use client';\nimport ServerInfo from '.\u002Fserver-info'; \u002F\u002F server-info.js is an RSC\n\nexport default function ClientWrapper() {\n  \u002F\u002F ❌ Error: Cannot import a Server Component into a Client Component.\n  return \u003CServerInfo \u002F>;\n}\n",[1053],{"type":504,"tag":606,"props":1054,"children":1055},{"__ignoreMap":902},[1056,1064,1076,1106,1113,1137,1145,1165],{"type":504,"tag":908,"props":1057,"children":1058},{"class":910,"line":911},[1059],{"type":504,"tag":908,"props":1060,"children":1061},{"style":915},[1062],{"type":510,"value":1063},"\u002F\u002F client-component.js\n",{"type":504,"tag":908,"props":1065,"children":1066},{"class":910,"line":921},[1067,1071],{"type":504,"tag":908,"props":1068,"children":1069},{"style":942},[1070],{"type":510,"value":736},{"type":504,"tag":908,"props":1072,"children":1073},{"style":931},[1074],{"type":510,"value":1075},";\n",{"type":504,"tag":908,"props":1077,"children":1078},{"class":910,"line":958},[1079,1083,1088,1092,1097,1101],{"type":504,"tag":908,"props":1080,"children":1081},{"style":925},[1082],{"type":510,"value":928},{"type":504,"tag":908,"props":1084,"children":1085},{"style":931},[1086],{"type":510,"value":1087}," ServerInfo ",{"type":504,"tag":908,"props":1089,"children":1090},{"style":925},[1091],{"type":510,"value":939},{"type":504,"tag":908,"props":1093,"children":1094},{"style":942},[1095],{"type":510,"value":1096}," '.\u002Fserver-info'",{"type":504,"tag":908,"props":1098,"children":1099},{"style":931},[1100],{"type":510,"value":950},{"type":504,"tag":908,"props":1102,"children":1103},{"style":915},[1104],{"type":510,"value":1105},"\u002F\u002F server-info.js is an RSC\n",{"type":504,"tag":908,"props":1107,"children":1108},{"class":910,"line":968},[1109],{"type":504,"tag":908,"props":1110,"children":1111},{"emptyLinePlaceholder":962},[1112],{"type":510,"value":965},{"type":504,"tag":908,"props":1114,"children":1115},{"class":910,"line":998},[1116,1120,1124,1128,1133],{"type":504,"tag":908,"props":1117,"children":1118},{"style":925},[1119],{"type":510,"value":974},{"type":504,"tag":908,"props":1121,"children":1122},{"style":925},[1123],{"type":510,"value":979},{"type":504,"tag":908,"props":1125,"children":1126},{"style":925},[1127],{"type":510,"value":984},{"type":504,"tag":908,"props":1129,"children":1130},{"style":987},[1131],{"type":510,"value":1132}," ClientWrapper",{"type":504,"tag":908,"props":1134,"children":1135},{"style":931},[1136],{"type":510,"value":995},{"type":504,"tag":908,"props":1138,"children":1139},{"class":910,"line":1007},[1140],{"type":504,"tag":908,"props":1141,"children":1142},{"style":915},[1143],{"type":510,"value":1144},"  \u002F\u002F ❌ Error: Cannot import a Server Component into a Client Component.\n",{"type":504,"tag":908,"props":1146,"children":1147},{"class":910,"line":1032},[1148,1152,1156,1161],{"type":504,"tag":908,"props":1149,"children":1150},{"style":925},[1151],{"type":510,"value":1013},{"type":504,"tag":908,"props":1153,"children":1154},{"style":931},[1155],{"type":510,"value":1018},{"type":504,"tag":908,"props":1157,"children":1158},{"style":1021},[1159],{"type":510,"value":1160},"ServerInfo",{"type":504,"tag":908,"props":1162,"children":1163},{"style":931},[1164],{"type":510,"value":1029},{"type":504,"tag":908,"props":1166,"children":1168},{"class":910,"line":1167},8,[1169],{"type":504,"tag":908,"props":1170,"children":1171},{"style":931},[1172],{"type":510,"value":1038},{"type":504,"tag":548,"props":1174,"children":1175},{},[1176,1189,1191,1196,1198,1381,1385,1387,1393,1395,1400,1402,1407,1409,1415,1417,1422],{"type":504,"tag":520,"props":1177,"children":1178},{},[1179,1181,1187],{"type":510,"value":1180},"【关键模式】通过 ",{"type":504,"tag":606,"props":1182,"children":1184},{"className":1183},[],[1185],{"type":510,"value":1186},"children",{"type":510,"value":1188}," props 实现嵌套",{"type":510,"value":1190},"：你可以将 RSC 作为 ",{"type":504,"tag":606,"props":1192,"children":1194},{"className":1193},[],[1195],{"type":510,"value":1186},{"type":510,"value":1197}," 或其他 prop 传递给一个客户端组件。",{"type":504,"tag":897,"props":1199,"children":1201},{"className":899,"code":1200,"language":901,"meta":902,"style":902},"\u002F\u002F server-component.js\nimport ClientWrapper from '.\u002Fclient-wrapper';\nimport ServerInfo from '.\u002Fserver-info';\n\nexport default function ServerPage() {\n  \u002F\u002F ✅ OK: ServerInfo is rendered on the server, and its result is passed to ClientWrapper\n  return (\n    \u003CClientWrapper>\n      \u003CServerInfo \u002F>\n    \u003C\u002FClientWrapper>\n  );\n}\n",[1202],{"type":504,"tag":606,"props":1203,"children":1204},{"__ignoreMap":902},[1205,1213,1238,1261,1268,1291,1299,1311,1329,1347,1364,1373],{"type":504,"tag":908,"props":1206,"children":1207},{"class":910,"line":911},[1208],{"type":504,"tag":908,"props":1209,"children":1210},{"style":915},[1211],{"type":510,"value":1212},"\u002F\u002F server-component.js\n",{"type":504,"tag":908,"props":1214,"children":1215},{"class":910,"line":921},[1216,1220,1225,1229,1234],{"type":504,"tag":908,"props":1217,"children":1218},{"style":925},[1219],{"type":510,"value":928},{"type":504,"tag":908,"props":1221,"children":1222},{"style":931},[1223],{"type":510,"value":1224}," ClientWrapper ",{"type":504,"tag":908,"props":1226,"children":1227},{"style":925},[1228],{"type":510,"value":939},{"type":504,"tag":908,"props":1230,"children":1231},{"style":942},[1232],{"type":510,"value":1233}," '.\u002Fclient-wrapper'",{"type":504,"tag":908,"props":1235,"children":1236},{"style":931},[1237],{"type":510,"value":1075},{"type":504,"tag":908,"props":1239,"children":1240},{"class":910,"line":958},[1241,1245,1249,1253,1257],{"type":504,"tag":908,"props":1242,"children":1243},{"style":925},[1244],{"type":510,"value":928},{"type":504,"tag":908,"props":1246,"children":1247},{"style":931},[1248],{"type":510,"value":1087},{"type":504,"tag":908,"props":1250,"children":1251},{"style":925},[1252],{"type":510,"value":939},{"type":504,"tag":908,"props":1254,"children":1255},{"style":942},[1256],{"type":510,"value":1096},{"type":504,"tag":908,"props":1258,"children":1259},{"style":931},[1260],{"type":510,"value":1075},{"type":504,"tag":908,"props":1262,"children":1263},{"class":910,"line":968},[1264],{"type":504,"tag":908,"props":1265,"children":1266},{"emptyLinePlaceholder":962},[1267],{"type":510,"value":965},{"type":504,"tag":908,"props":1269,"children":1270},{"class":910,"line":998},[1271,1275,1279,1283,1287],{"type":504,"tag":908,"props":1272,"children":1273},{"style":925},[1274],{"type":510,"value":974},{"type":504,"tag":908,"props":1276,"children":1277},{"style":925},[1278],{"type":510,"value":979},{"type":504,"tag":908,"props":1280,"children":1281},{"style":925},[1282],{"type":510,"value":984},{"type":504,"tag":908,"props":1284,"children":1285},{"style":987},[1286],{"type":510,"value":990},{"type":504,"tag":908,"props":1288,"children":1289},{"style":931},[1290],{"type":510,"value":995},{"type":504,"tag":908,"props":1292,"children":1293},{"class":910,"line":1007},[1294],{"type":504,"tag":908,"props":1295,"children":1296},{"style":915},[1297],{"type":510,"value":1298},"  \u002F\u002F ✅ OK: ServerInfo is rendered on the server, and its result is passed to ClientWrapper\n",{"type":504,"tag":908,"props":1300,"children":1301},{"class":910,"line":1032},[1302,1306],{"type":504,"tag":908,"props":1303,"children":1304},{"style":925},[1305],{"type":510,"value":1013},{"type":504,"tag":908,"props":1307,"children":1308},{"style":931},[1309],{"type":510,"value":1310}," (\n",{"type":504,"tag":908,"props":1312,"children":1313},{"class":910,"line":1167},[1314,1319,1324],{"type":504,"tag":908,"props":1315,"children":1316},{"style":931},[1317],{"type":510,"value":1318},"    \u003C",{"type":504,"tag":908,"props":1320,"children":1321},{"style":1021},[1322],{"type":510,"value":1323},"ClientWrapper",{"type":504,"tag":908,"props":1325,"children":1326},{"style":931},[1327],{"type":510,"value":1328},">\n",{"type":504,"tag":908,"props":1330,"children":1332},{"class":910,"line":1331},9,[1333,1338,1342],{"type":504,"tag":908,"props":1334,"children":1335},{"style":931},[1336],{"type":510,"value":1337},"      \u003C",{"type":504,"tag":908,"props":1339,"children":1340},{"style":1021},[1341],{"type":510,"value":1160},{"type":504,"tag":908,"props":1343,"children":1344},{"style":931},[1345],{"type":510,"value":1346}," \u002F>\n",{"type":504,"tag":908,"props":1348,"children":1350},{"class":910,"line":1349},10,[1351,1356,1360],{"type":504,"tag":908,"props":1352,"children":1353},{"style":931},[1354],{"type":510,"value":1355},"    \u003C\u002F",{"type":504,"tag":908,"props":1357,"children":1358},{"style":1021},[1359],{"type":510,"value":1323},{"type":504,"tag":908,"props":1361,"children":1362},{"style":931},[1363],{"type":510,"value":1328},{"type":504,"tag":908,"props":1365,"children":1367},{"class":910,"line":1366},11,[1368],{"type":504,"tag":908,"props":1369,"children":1370},{"style":931},[1371],{"type":510,"value":1372},"  );\n",{"type":504,"tag":908,"props":1374,"children":1376},{"class":910,"line":1375},12,[1377],{"type":504,"tag":908,"props":1378,"children":1379},{"style":931},[1380],{"type":510,"value":1038},{"type":504,"tag":1382,"props":1383,"children":1384},"br",{},[],{"type":510,"value":1386},"在这个模式中，",{"type":504,"tag":606,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":510,"value":1392},"\u003CServerInfo \u002F>",{"type":510,"value":1394}," 在服务器上被渲染成 VDOM 描述格式，然后这个",{"type":504,"tag":520,"props":1396,"children":1397},{},[1398],{"type":510,"value":1399},"结果",{"type":510,"value":1401},"作为 ",{"type":504,"tag":606,"props":1403,"children":1405},{"className":1404},[],[1406],{"type":510,"value":1186},{"type":510,"value":1408}," prop 被传递给 ",{"type":504,"tag":606,"props":1410,"children":1412},{"className":1411},[],[1413],{"type":510,"value":1414},"\u003CClientWrapper \u002F>",{"type":510,"value":1416},"。客户端只“看到”渲染结果，而不知道 ",{"type":504,"tag":606,"props":1418,"children":1420},{"className":1419},[],[1421],{"type":510,"value":1160},{"type":510,"value":1423}," 的存在。",{"type":504,"tag":528,"props":1425,"children":1426},{},[],{"type":504,"tag":532,"props":1428,"children":1430},{"id":1429},"_3-深水区约束与挑战",[1431],{"type":510,"value":1432},"3. 深水区：约束与挑战",{"type":504,"tag":725,"props":1434,"children":1436},{"id":1435},"a-状态管理边界与鸿沟",[1437],{"type":510,"value":1438},"A. 状态管理：边界与鸿沟",{"type":504,"tag":544,"props":1440,"children":1441},{},[1442,1459],{"type":504,"tag":548,"props":1443,"children":1444},{},[1445,1450,1452,1457],{"type":504,"tag":520,"props":1446,"children":1447},{},[1448],{"type":510,"value":1449},"全局状态的割裂",{"type":510,"value":1451},"：传统的客户端全局状态管理（如 Context, Redux）只能在 ",{"type":504,"tag":606,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":510,"value":736},{"type":510,"value":1458}," 树内部共享。RSC 完全无法访问这些状态。",{"type":504,"tag":548,"props":1460,"children":1461},{},[1462,1467,1469,1474,1476],{"type":504,"tag":520,"props":1463,"children":1464},{},[1465],{"type":510,"value":1466},"URL 成为新的“全局状态”",{"type":510,"value":1468},"：对于需要同时影响 RSC 和客户端组件的状态，",{"type":504,"tag":520,"props":1470,"children":1471},{},[1472],{"type":510,"value":1473},"URL (search params)",{"type":510,"value":1475}," 成为了事实上的唯一通信渠道。\n",{"type":504,"tag":544,"props":1477,"children":1478},{},[1479,1489],{"type":504,"tag":548,"props":1480,"children":1481},{},[1482,1487],{"type":504,"tag":520,"props":1483,"children":1484},{},[1485],{"type":510,"value":1486},"场景",{"type":510,"value":1488},"：一个搜索框（客户端组件）需要更新一个商品列表（RSC）。",{"type":504,"tag":548,"props":1490,"children":1491},{},[1492,1497,1499,1505,1507,1513],{"type":504,"tag":520,"props":1493,"children":1494},{},[1495],{"type":510,"value":1496},"流程",{"type":510,"value":1498},"：搜索框输入 -> 使用 ",{"type":504,"tag":606,"props":1500,"children":1502},{"className":1501},[],[1503],{"type":510,"value":1504},"useRouter",{"type":510,"value":1506}," 更新 URL (",{"type":504,"tag":606,"props":1508,"children":1510},{"className":1509},[],[1511],{"type":510,"value":1512},"\u002Fproducts?q=...",{"type":510,"value":1514},") -> 框架（如 Next.js）检测到 URL 变化 -> 自动重新请求并渲染服务器上的商品列表 RSC。",{"type":504,"tag":725,"props":1516,"children":1518},{"id":1517},"b-缓存与数据一致性",[1519],{"type":510,"value":1520},"B. 缓存与数据一致性",{"type":504,"tag":516,"props":1522,"children":1523},{},[1524],{"type":510,"value":1525},"RSC 的渲染结果在服务器上被积极地缓存。如何确保数据变更后，UI能及时更新？",{"type":504,"tag":544,"props":1527,"children":1528},{},[1529,1550,1612],{"type":504,"tag":548,"props":1530,"children":1531},{},[1532,1541,1543,1548],{"type":504,"tag":520,"props":1533,"children":1534},{},[1535],{"type":504,"tag":606,"props":1536,"children":1538},{"className":1537},[],[1539],{"type":510,"value":1540},"router.refresh()",{"type":510,"value":1542},"：由客户端发起，它会",{"type":504,"tag":520,"props":1544,"children":1545},{},[1546],{"type":510,"value":1547},"重新请求当前路由的所有 RSC",{"type":510,"value":1549},"，并与客户端 DOM 进行“智能”合并（保留客户端状态）。这是一个成本较高但简单有效的刷新方式。",{"type":504,"tag":548,"props":1551,"children":1552},{},[1553,1570,1572],{"type":504,"tag":520,"props":1554,"children":1555},{},[1556,1562,1564],{"type":504,"tag":606,"props":1557,"children":1559},{"className":1558},[],[1560],{"type":510,"value":1561},"revalidatePath()",{"type":510,"value":1563}," \u002F ",{"type":504,"tag":606,"props":1565,"children":1567},{"className":1566},[],[1568],{"type":510,"value":1569},"revalidateTag()",{"type":510,"value":1571},"：在 Server Action 中调用，由服务器主动使缓存失效。\n",{"type":504,"tag":544,"props":1573,"children":1574},{},[1575,1594],{"type":504,"tag":548,"props":1576,"children":1577},{},[1578,1584,1586,1592],{"type":504,"tag":606,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":510,"value":1583},"revalidatePath('\u002Fproducts')",{"type":510,"value":1585},"：使 ",{"type":504,"tag":606,"props":1587,"children":1589},{"className":1588},[],[1590],{"type":510,"value":1591},"\u002Fproducts",{"type":510,"value":1593}," 路由下的所有数据缓存失效。",{"type":504,"tag":548,"props":1595,"children":1596},{},[1597,1603,1605,1610],{"type":504,"tag":606,"props":1598,"children":1600},{"className":1599},[],[1601],{"type":510,"value":1602},"revalidateTag('products')",{"type":510,"value":1604},"：更精细的控制。在 ",{"type":504,"tag":606,"props":1606,"children":1608},{"className":1607},[],[1609],{"type":510,"value":707},{"type":510,"value":1611}," 时为数据打上标签，然后可以精确地让带有此标签的数据失效。",{"type":504,"tag":548,"props":1613,"children":1614},{},[1615,1626],{"type":504,"tag":520,"props":1616,"children":1617},{},[1618,1620],{"type":510,"value":1619},"乐观更新 ",{"type":504,"tag":606,"props":1621,"children":1623},{"className":1622},[],[1624],{"type":510,"value":1625},"useOptimistic",{"type":510,"value":1627},"：在 Server Action 执行期间，可以先在 UI 上展示一个“乐观”的状态。React 会在后台处理 Server Action，并在其完成后，用真实结果替换乐观状态。这是实现高性能交互体验的关键。",{"type":504,"tag":725,"props":1629,"children":1631},{"id":1630},"c-序列化约束",[1632],{"type":510,"value":1633},"C. 序列化约束",{"type":504,"tag":516,"props":1635,"children":1636},{},[1637,1639,1644,1646,1652,1654,1660,1661,1667],{"type":510,"value":1638},"从服务器组件传递到客户端组件的 props ",{"type":504,"tag":520,"props":1640,"children":1641},{},[1642],{"type":510,"value":1643},"必须是可序列化的",{"type":510,"value":1645},"。这意味着你不能传递函数（除非是 Server Actions）、",{"type":504,"tag":606,"props":1647,"children":1649},{"className":1648},[],[1650],{"type":510,"value":1651},"Date",{"type":510,"value":1653},"、",{"type":504,"tag":606,"props":1655,"children":1657},{"className":1656},[],[1658],{"type":510,"value":1659},"Map",{"type":510,"value":1653},{"type":504,"tag":606,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":510,"value":1666},"Set",{"type":510,"value":1668}," 等非原生 JSON 支持的类型。",{"type":504,"tag":544,"props":1670,"children":1671},{},[1672,1689],{"type":504,"tag":548,"props":1673,"children":1674},{},[1675,1680,1682,1687],{"type":504,"tag":520,"props":1676,"children":1677},{},[1678],{"type":510,"value":1679},"常见错误",{"type":510,"value":1681},"：在 RSC 中获取数据，然后将一个 ",{"type":504,"tag":606,"props":1683,"children":1685},{"className":1684},[],[1686],{"type":510,"value":1651},{"type":510,"value":1688}," 对象直接传给一个客户端组件。",{"type":504,"tag":548,"props":1690,"children":1691},{},[1692,1697],{"type":504,"tag":520,"props":1693,"children":1694},{},[1695],{"type":510,"value":1696},"解决方案",{"type":510,"value":1698},"：在传递前，先在 RSC 中将其格式化为字符串。",{"type":504,"tag":528,"props":1700,"children":1701},{},[],{"type":504,"tag":532,"props":1703,"children":1705},{"id":1704},"_4-实践中的权衡",[1706],{"type":510,"value":1707},"4. 实践中的权衡",{"type":504,"tag":544,"props":1709,"children":1710},{},[1711,1734,1752],{"type":504,"tag":548,"props":1712,"children":1713},{},[1714,1719,1721,1726,1727,1732],{"type":504,"tag":520,"props":1715,"children":1716},{},[1717],{"type":510,"value":1718},"默认使用 RSC",{"type":510,"value":1720},"：除非你需要客户端交互 (",{"type":504,"tag":606,"props":1722,"children":1724},{"className":1723},[],[1725],{"type":510,"value":619},{"type":510,"value":621},{"type":504,"tag":606,"props":1728,"children":1730},{"className":1729},[],[1731],{"type":510,"value":627},{"type":510,"value":1733},", 事件监听)，否则都应该保持为 RSC。这能最大化性能优势。",{"type":504,"tag":548,"props":1735,"children":1736},{},[1737,1750],{"type":504,"tag":520,"props":1738,"children":1739},{},[1740,1742,1748],{"type":510,"value":1741},"将 ",{"type":504,"tag":606,"props":1743,"children":1745},{"className":1744},[],[1746],{"type":510,"value":1747},"use client",{"type":510,"value":1749}," “下沉”",{"type":510,"value":1751},"：将客户端交互逻辑尽可能地封装在叶子组件中。例如，一个包含静态标题和交互式按钮的卡片，应该将卡片本身作为 RSC，而只将按钮做成客户端组件。",{"type":504,"tag":548,"props":1753,"children":1754},{},[1755,1760,1762,1768],{"type":504,"tag":520,"props":1756,"children":1757},{},[1758],{"type":510,"value":1759},"拥抱渐进式增强",{"type":510,"value":1761},"：Server Actions 与原生 ",{"type":504,"tag":606,"props":1763,"children":1765},{"className":1764},[],[1766],{"type":510,"value":1767},"\u003Cform>",{"type":510,"value":1769}," 的结合是渐进式增强的完美体现。即使 JS 加载失败，表单依然可以工作。",{"type":504,"tag":516,"props":1771,"children":1772},{},[1773],{"type":510,"value":1774},"RSC 和 Server Actions 是一种范式转移。它们要求开发者更清晰地思考“什么逻辑应该在哪里运行”，这带来了更高的心智负担，但作为回报，它也带来了前所未有的性能潜力和更简洁的数据变更模型。",{"type":504,"tag":528,"props":1776,"children":1777},{},[],{"type":504,"tag":532,"props":1779,"children":1781},{"id":1780},"_5-关联阅读",[1782],{"type":510,"value":1783},"5. 关联阅读",{"type":504,"tag":544,"props":1785,"children":1786},{},[1787,1813],{"type":504,"tag":548,"props":1788,"children":1789},{},[1790,1795,1797,1806,1807],{"type":504,"tag":520,"props":1791,"children":1792},{},[1793],{"type":510,"value":1794},"React 官方文档",{"type":510,"value":1796},": ",{"type":504,"tag":1798,"props":1799,"children":1803},"a",{"href":1800,"rel":1801},"https:\u002F\u002Freact.dev\u002Freference\u002Freact\u002Fuse-server",[1802],"nofollow",[1804],{"type":510,"value":1805},"Server Components",{"type":510,"value":621},{"type":504,"tag":1798,"props":1808,"children":1811},{"href":1809,"rel":1810},"https:\u002F\u002Freact.dev\u002Freference\u002Freact\u002Fuse-action-state",[1802],[1812],{"type":510,"value":647},{"type":504,"tag":548,"props":1814,"children":1815},{},[1816,1821,1822],{"type":504,"tag":520,"props":1817,"children":1818},{},[1819],{"type":510,"value":1820},"Next.js 官方文档",{"type":510,"value":1796},{"type":504,"tag":1798,"props":1823,"children":1826},{"href":1824,"rel":1825},"https:\u002F\u002Fnextjs.org\u002Fdocs\u002Fgetting-started\u002Freact-essentials",[1802],[1827],{"type":510,"value":1828},"React Foundations",{"type":504,"tag":1830,"props":1831,"children":1832},"style",{},[1833],{"type":510,"value":1834},"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":902,"searchDepth":921,"depth":921,"links":1836},[1837,1838,1845,1850,1851],{"id":534,"depth":921,"text":537},{"id":715,"depth":921,"text":718,"children":1839},[1840,1842,1844],{"id":727,"depth":958,"text":1841},"A. 'use client'",{"id":840,"depth":958,"text":1843},"B. 'use server'",{"id":874,"depth":958,"text":877},{"id":1429,"depth":921,"text":1432,"children":1846},[1847,1848,1849],{"id":1435,"depth":958,"text":1438},{"id":1517,"depth":958,"text":1520},{"id":1630,"depth":958,"text":1633},{"id":1704,"depth":921,"text":1707},{"id":1780,"depth":921,"text":1783},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1853},"\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":1855},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm0 7h12v2H3zm0 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":1857},"\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":1859,"height":1859,"rotate":4,"vFlip":6,"hFlip":6,"body":1860},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>"]