[{"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-12-rendering-and-delivery\u002F01-nextjs-cache-revalidate-consistency-online-not-updating":494,"i-ri:arrow-left-s-line":3348,"i-ri:menu-2-line":3350,"i-ri:arrow-right-s-line":3352,"i-ep:copy-document":3354},{"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":407,"path":407,"title":408,"updatedAt":21,"meta":498,"body":500,"toc":3307},"bm90ZTpub3Rlcy9yZWFjdC8xMi1yZW5kZXJpbmctYW5kLWRlbGl2ZXJ5LzAxLW5leHRqcy1jYWNoZS1yZXZhbGlkYXRlLWNvbnNpc3RlbmN5LW9ubGluZS1ub3QtdXBkYXRpbmcubWQ","note","notes\u002Freact\u002F12-rendering-and-delivery\u002F01-nextjs-cache-revalidate-consistency-online-not-updating.md",{"id":495,"type":496,"sourcePath":497,"slug":499,"title":408,"updatedAt":21,"lastUpdated":21},"react\u002F12-rendering-and-delivery\u002F01-nextjs-cache-revalidate-consistency-online-not-updating",{"type":501,"children":502},"root",[503,511,576,583,595,630,642,664,676,705,710,716,721,744,749,756,784,792,798,830,835,979,985,990,1122,1127,1158,1181,1187,1192,1218,1223,1247,1253,1259,1278,1283,1313,1319,1324,1349,1364,1370,1387,1391,1418,1424,1429,1449,1454,1495,1500,1728,1733,1912,1917,2025,2031,2037,2056,2074,2087,2107,2112,2139,2152,2176,2180,2196,2202,2207,2226,2230,2263,2276,2296,2300,2325,2331,2344,2348,2377,2383,2389,2430,2436,2458,2464,2540,2546,2596,2602,2632,2638,2644,2649,2689,2694,2978,2983,2996,3002,3015,3021,3082,3088,3114,3120,3125,3160,3172,3177,3301],{"type":504,"tag":505,"props":506,"children":508},"element","h1",{"id":507},"nextjs-缓存重验证与一致性避免线上怎么不更新事故app-router",[509],{"type":510,"value":408},"text",{"type":504,"tag":512,"props":513,"children":514},"blockquote",{},[515,529,564],{"type":504,"tag":516,"props":517,"children":518},"p",{},[519,521,527],{"type":510,"value":520},"一句话结论：App Router 下的“数据是否更新”不是一个开关，而是",{"type":504,"tag":522,"props":523,"children":524},"strong",{},[525],{"type":510,"value":526},"多层缓存共同作用的结果",{"type":510,"value":528},"：",{"type":504,"tag":530,"props":531,"children":532},"ul",{},[533,539,549,554],{"type":504,"tag":534,"props":535,"children":536},"li",{},[537],{"type":510,"value":538},"**fetch\u002FData Cache（跨请求）**决定“服务端这次渲染用的是什么数据”",{"type":504,"tag":534,"props":540,"children":541},{},[542,547],{"type":504,"tag":522,"props":543,"children":544},{},[545],{"type":510,"value":546},"route 级别的静态化\u002F重验证",{"type":510,"value":548},"决定“这条路由的 RSC\u002FHTML 会不会被复用”",{"type":504,"tag":534,"props":550,"children":551},{},[552],{"type":510,"value":553},"**Route Segment Cache（客户端路由缓存）**决定“用户在浏览器里导航时会不会继续看到旧的 RSC payload”",{"type":504,"tag":534,"props":555,"children":556},{},[557,559],{"type":510,"value":558},"**Server Actions（写入）**不会自动让读路径一致，必须显式 ",{"type":504,"tag":522,"props":560,"children":561},{},[562],{"type":510,"value":563},"revalidate + refresh",{"type":504,"tag":516,"props":565,"children":566},{},[567,569,574],{"type":510,"value":568},"所谓「线上怎么不更新」，通常是：",{"type":504,"tag":522,"props":570,"children":571},{},[572],{"type":510,"value":573},"写已经成功，但读还在命中旧缓存",{"type":510,"value":575},"（而 dev 环境缓存弱\u002F不同，导致本地复现困难）。",{"type":504,"tag":577,"props":578,"children":580},"h2",{"id":579},"_0-你要先回答的-3-个问题定位方向",[581],{"type":510,"value":582},"0. 你要先回答的 3 个问题（定位方向）",{"type":504,"tag":584,"props":585,"children":586},"ol",{},[587],{"type":504,"tag":534,"props":588,"children":589},{},[590],{"type":504,"tag":522,"props":591,"children":592},{},[593],{"type":510,"value":594},"旧的是哪一层？",{"type":504,"tag":530,"props":596,"children":597},{},[598,608,618],{"type":504,"tag":534,"props":599,"children":600},{},[601,603],{"type":510,"value":602},"仅“站内跳转”旧，但硬刷新就新 → 多半是 ",{"type":504,"tag":522,"props":604,"children":605},{},[606],{"type":510,"value":607},"Route Segment Cache（客户端）",{"type":504,"tag":534,"props":609,"children":610},{},[611,613],{"type":510,"value":612},"硬刷新也旧，但等一会儿会变新 → 多半是 ",{"type":504,"tag":522,"props":614,"children":615},{},[616],{"type":510,"value":617},"ISR\u002Ftime-based revalidate",{"type":504,"tag":534,"props":619,"children":620},{},[621,623,628],{"type":510,"value":622},"过多久都不变（直到手动清缓存\u002F发版）→ 多半是 ",{"type":504,"tag":522,"props":624,"children":625},{},[626],{"type":510,"value":627},"Data Cache \u002F Full Route Cache \u002F unstable_cache",{"type":510,"value":629}," 没有失效",{"type":504,"tag":584,"props":631,"children":633},{"start":632},2,[634],{"type":504,"tag":534,"props":635,"children":636},{},[637],{"type":504,"tag":522,"props":638,"children":639},{},[640],{"type":510,"value":641},"这是公共数据还是用户态数据？",{"type":504,"tag":530,"props":643,"children":644},{},[645,650],{"type":504,"tag":534,"props":646,"children":647},{},[648],{"type":510,"value":649},"公共数据（资讯、商品详情、榜单）适合 cache + revalidate\u002Ftag",{"type":504,"tag":534,"props":651,"children":652},{},[653,655,662],{"type":510,"value":654},"用户态数据（购物车、权限、个性化 feed）通常应 ",{"type":504,"tag":656,"props":657,"children":659},"code",{"className":658},[],[660],{"type":510,"value":661},"no-store",{"type":510,"value":663}," 或强动态",{"type":504,"tag":584,"props":665,"children":667},{"start":666},3,[668],{"type":504,"tag":534,"props":669,"children":670},{},[671],{"type":504,"tag":522,"props":672,"children":673},{},[674],{"type":510,"value":675},"读路径和写路径是否在同一个“缓存一致性协议”里？",{"type":504,"tag":530,"props":677,"children":678},{},[679,684],{"type":504,"tag":534,"props":680,"children":681},{},[682],{"type":510,"value":683},"写：Server Action \u002F API Route \u002F 后台任务",{"type":504,"tag":534,"props":685,"children":686},{},[687,689,695,697,703],{"type":510,"value":688},"读：RSC ",{"type":504,"tag":656,"props":690,"children":692},{"className":691},[],[693],{"type":510,"value":694},"fetch",{"type":510,"value":696}," \u002F ",{"type":504,"tag":656,"props":698,"children":700},{"className":699},[],[701],{"type":510,"value":702},"unstable_cache",{"type":510,"value":704}," \u002F Client Query",{"type":504,"tag":516,"props":706,"children":707},{},[708],{"type":510,"value":709},"如果读和写分别被不同体系缓存（Next fetch cache + 浏览器 route cache + React Query），一致性问题是必然的。",{"type":504,"tag":577,"props":711,"children":713},{"id":712},"_1-心智模型app-router-的4-层缓存",[714],{"type":510,"value":715},"1. 心智模型：App Router 的“4 层缓存”",{"type":504,"tag":516,"props":717,"children":718},{},[719],{"type":510,"value":720},"把一次页面展示拆成两段：",{"type":504,"tag":530,"props":722,"children":723},{},[724,734],{"type":504,"tag":534,"props":725,"children":726},{},[727,732],{"type":504,"tag":522,"props":728,"children":729},{},[730],{"type":510,"value":731},"服务端渲染（RSC 生成）",{"type":510,"value":733},"：决定“这次渲染拿到的数据”",{"type":504,"tag":534,"props":735,"children":736},{},[737,742],{"type":504,"tag":522,"props":738,"children":739},{},[740],{"type":510,"value":741},"客户端导航（soft navigation）",{"type":510,"value":743},"：决定“用户在 SPA 式导航中是否复用旧的 RSC payload”",{"type":504,"tag":516,"props":745,"children":746},{},[747],{"type":510,"value":748},"对应常见缓存层（命名按工程理解，不是官方唯一术语）：",{"type":504,"tag":750,"props":751,"children":753},"h3",{"id":752},"_11-request-级reactnext-的请求内去重不是罪魁祸首",[754],{"type":510,"value":755},"1.1 Request 级：React\u002FNext 的请求内去重（不是罪魁祸首）",{"type":504,"tag":530,"props":757,"children":758},{},[759,772],{"type":504,"tag":534,"props":760,"children":761},{},[762,764,770],{"type":510,"value":763},"同一次 RSC 渲染里，同样的 ",{"type":504,"tag":656,"props":765,"children":767},{"className":766},[],[768],{"type":510,"value":769},"fetch(url, options)",{"type":510,"value":771}," 会被去重\u002F复用",{"type":504,"tag":534,"props":773,"children":774},{},[775,777,782],{"type":510,"value":776},"作用范围通常是",{"type":504,"tag":522,"props":778,"children":779},{},[780],{"type":510,"value":781},"单次请求\u002F单次渲染",{"type":510,"value":783},"，不会导致“线上永远不更新”",{"type":504,"tag":512,"props":785,"children":786},{},[787],{"type":504,"tag":516,"props":788,"children":789},{},[790],{"type":510,"value":791},"排查时不要把“去重”当作跨请求的缓存。",{"type":504,"tag":750,"props":793,"children":795},{"id":794},"_12-data-cachenext-增强-fetch-的跨请求缓存高频事故源",[796],{"type":510,"value":797},"1.2 Data Cache：Next 增强 fetch 的“跨请求缓存”（高频事故源）",{"type":504,"tag":530,"props":799,"children":800},{},[801,812],{"type":504,"tag":534,"props":802,"children":803},{},[804,810],{"type":504,"tag":656,"props":805,"children":807},{"className":806},[],[808],{"type":510,"value":809},"fetch()",{"type":510,"value":811}," 在 App Router 中不是纯浏览器 fetch，而是 Next 包装过的版本",{"type":504,"tag":534,"props":813,"children":814},{},[815,817],{"type":510,"value":816},"当命中 Data Cache：\n",{"type":504,"tag":530,"props":818,"children":819},{},[820,825],{"type":504,"tag":534,"props":821,"children":822},{},[823],{"type":510,"value":824},"服务端生成 RSC 时会直接复用旧响应",{"type":504,"tag":534,"props":826,"children":827},{},[828],{"type":510,"value":829},"你的代码看起来“又执行了 fetch”，但实际上返回的是缓存结果",{"type":504,"tag":516,"props":831,"children":832},{},[833],{"type":510,"value":834},"关键 knobs（常用）：",{"type":504,"tag":836,"props":837,"children":842},"pre",{"className":838,"code":839,"language":840,"meta":841,"style":841},"language-ts shiki shiki-themes github-light github-dark","fetch(url, {\n  cache: 'force-cache' | 'no-store',\n  next: {\n    revalidate: 60,        \u002F\u002F 秒：time-based ISR for this request\n    tags: ['posts', 'post:123'], \u002F\u002F 用于 on-demand revalidateTag\n  },\n})\n","ts","",[843],{"type":504,"tag":656,"props":844,"children":845},{"__ignoreMap":841},[846,863,893,901,927,961,970],{"type":504,"tag":847,"props":848,"children":851},"span",{"class":849,"line":850},"line",1,[852,857],{"type":504,"tag":847,"props":853,"children":855},{"style":854},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[856],{"type":510,"value":694},{"type":504,"tag":847,"props":858,"children":860},{"style":859},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[861],{"type":510,"value":862},"(url, {\n",{"type":504,"tag":847,"props":864,"children":865},{"class":849,"line":632},[866,871,877,883,888],{"type":504,"tag":847,"props":867,"children":868},{"style":859},[869],{"type":510,"value":870},"  cache: ",{"type":504,"tag":847,"props":872,"children":874},{"style":873},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[875],{"type":510,"value":876},"'force-cache'",{"type":504,"tag":847,"props":878,"children":880},{"style":879},"--shiki-default:#D73A49;--shiki-dark:#F97583",[881],{"type":510,"value":882}," |",{"type":504,"tag":847,"props":884,"children":885},{"style":873},[886],{"type":510,"value":887}," 'no-store'",{"type":504,"tag":847,"props":889,"children":890},{"style":859},[891],{"type":510,"value":892},",\n",{"type":504,"tag":847,"props":894,"children":895},{"class":849,"line":666},[896],{"type":504,"tag":847,"props":897,"children":898},{"style":859},[899],{"type":510,"value":900},"  next: {\n",{"type":504,"tag":847,"props":902,"children":904},{"class":849,"line":903},4,[905,910,916,921],{"type":504,"tag":847,"props":906,"children":907},{"style":859},[908],{"type":510,"value":909},"    revalidate: ",{"type":504,"tag":847,"props":911,"children":913},{"style":912},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[914],{"type":510,"value":915},"60",{"type":504,"tag":847,"props":917,"children":918},{"style":859},[919],{"type":510,"value":920},",        ",{"type":504,"tag":847,"props":922,"children":924},{"style":923},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[925],{"type":510,"value":926},"\u002F\u002F 秒：time-based ISR for this request\n",{"type":504,"tag":847,"props":928,"children":930},{"class":849,"line":929},5,[931,936,941,946,951,956],{"type":504,"tag":847,"props":932,"children":933},{"style":859},[934],{"type":510,"value":935},"    tags: [",{"type":504,"tag":847,"props":937,"children":938},{"style":873},[939],{"type":510,"value":940},"'posts'",{"type":504,"tag":847,"props":942,"children":943},{"style":859},[944],{"type":510,"value":945},", ",{"type":504,"tag":847,"props":947,"children":948},{"style":873},[949],{"type":510,"value":950},"'post:123'",{"type":504,"tag":847,"props":952,"children":953},{"style":859},[954],{"type":510,"value":955},"], ",{"type":504,"tag":847,"props":957,"children":958},{"style":923},[959],{"type":510,"value":960},"\u002F\u002F 用于 on-demand revalidateTag\n",{"type":504,"tag":847,"props":962,"children":964},{"class":849,"line":963},6,[965],{"type":504,"tag":847,"props":966,"children":967},{"style":859},[968],{"type":510,"value":969},"  },\n",{"type":504,"tag":847,"props":971,"children":973},{"class":849,"line":972},7,[974],{"type":504,"tag":847,"props":975,"children":976},{"style":859},[977],{"type":510,"value":978},"})\n",{"type":504,"tag":750,"props":980,"children":982},{"id":981},"_13-full-route-segment-静态化路由级别是否可复用宏观策略",[983],{"type":510,"value":984},"1.3 Full Route \u002F Segment 静态化：路由级别是否可复用（宏观策略）",{"type":504,"tag":516,"props":986,"children":987},{},[988],{"type":510,"value":989},"路由\u002Fsegment 的配置会影响“这条路由到底是静态、ISR 还是动态”。常用：",{"type":504,"tag":836,"props":991,"children":993},{"className":838,"code":992,"language":840,"meta":841,"style":841},"\u002F\u002F app\u002F...\u002Fpage.tsx or layout.tsx\nexport const revalidate = 60           \u002F\u002F 路由级 ISR（time-based）\nexport const dynamic = 'force-dynamic' \u002F\u002F 强制动态（不走静态缓存）\nexport const dynamic = 'force-static'  \u002F\u002F 强制静态（配合 generateStaticParams）\n\n\u002F\u002F Next 也提供 fetchCache 之类的配置（用于约束该段下 fetch 的默认行为）\n\u002F\u002F export const fetchCache = 'force-no-store' | 'force-cache' | ...\n",[994],{"type":504,"tag":656,"props":995,"children":996},{"__ignoreMap":841},[997,1005,1038,1068,1097,1106,1114],{"type":504,"tag":847,"props":998,"children":999},{"class":849,"line":850},[1000],{"type":504,"tag":847,"props":1001,"children":1002},{"style":923},[1003],{"type":510,"value":1004},"\u002F\u002F app\u002F...\u002Fpage.tsx or layout.tsx\n",{"type":504,"tag":847,"props":1006,"children":1007},{"class":849,"line":632},[1008,1013,1018,1023,1028,1033],{"type":504,"tag":847,"props":1009,"children":1010},{"style":879},[1011],{"type":510,"value":1012},"export",{"type":504,"tag":847,"props":1014,"children":1015},{"style":879},[1016],{"type":510,"value":1017}," const",{"type":504,"tag":847,"props":1019,"children":1020},{"style":912},[1021],{"type":510,"value":1022}," revalidate",{"type":504,"tag":847,"props":1024,"children":1025},{"style":879},[1026],{"type":510,"value":1027}," =",{"type":504,"tag":847,"props":1029,"children":1030},{"style":912},[1031],{"type":510,"value":1032}," 60",{"type":504,"tag":847,"props":1034,"children":1035},{"style":923},[1036],{"type":510,"value":1037},"           \u002F\u002F 路由级 ISR（time-based）\n",{"type":504,"tag":847,"props":1039,"children":1040},{"class":849,"line":666},[1041,1045,1049,1054,1058,1063],{"type":504,"tag":847,"props":1042,"children":1043},{"style":879},[1044],{"type":510,"value":1012},{"type":504,"tag":847,"props":1046,"children":1047},{"style":879},[1048],{"type":510,"value":1017},{"type":504,"tag":847,"props":1050,"children":1051},{"style":912},[1052],{"type":510,"value":1053}," dynamic",{"type":504,"tag":847,"props":1055,"children":1056},{"style":879},[1057],{"type":510,"value":1027},{"type":504,"tag":847,"props":1059,"children":1060},{"style":873},[1061],{"type":510,"value":1062}," 'force-dynamic'",{"type":504,"tag":847,"props":1064,"children":1065},{"style":923},[1066],{"type":510,"value":1067}," \u002F\u002F 强制动态（不走静态缓存）\n",{"type":504,"tag":847,"props":1069,"children":1070},{"class":849,"line":903},[1071,1075,1079,1083,1087,1092],{"type":504,"tag":847,"props":1072,"children":1073},{"style":879},[1074],{"type":510,"value":1012},{"type":504,"tag":847,"props":1076,"children":1077},{"style":879},[1078],{"type":510,"value":1017},{"type":504,"tag":847,"props":1080,"children":1081},{"style":912},[1082],{"type":510,"value":1053},{"type":504,"tag":847,"props":1084,"children":1085},{"style":879},[1086],{"type":510,"value":1027},{"type":504,"tag":847,"props":1088,"children":1089},{"style":873},[1090],{"type":510,"value":1091}," 'force-static'",{"type":504,"tag":847,"props":1093,"children":1094},{"style":923},[1095],{"type":510,"value":1096},"  \u002F\u002F 强制静态（配合 generateStaticParams）\n",{"type":504,"tag":847,"props":1098,"children":1099},{"class":849,"line":929},[1100],{"type":504,"tag":847,"props":1101,"children":1103},{"emptyLinePlaceholder":1102},true,[1104],{"type":510,"value":1105},"\n",{"type":504,"tag":847,"props":1107,"children":1108},{"class":849,"line":963},[1109],{"type":504,"tag":847,"props":1110,"children":1111},{"style":923},[1112],{"type":510,"value":1113},"\u002F\u002F Next 也提供 fetchCache 之类的配置（用于约束该段下 fetch 的默认行为）\n",{"type":504,"tag":847,"props":1115,"children":1116},{"class":849,"line":972},[1117],{"type":504,"tag":847,"props":1118,"children":1119},{"style":923},[1120],{"type":510,"value":1121},"\u002F\u002F export const fetchCache = 'force-no-store' | 'force-cache' | ...\n",{"type":504,"tag":516,"props":1123,"children":1124},{},[1125],{"type":510,"value":1126},"工程理解：",{"type":504,"tag":530,"props":1128,"children":1129},{},[1130,1148],{"type":504,"tag":534,"props":1131,"children":1132},{},[1133,1138,1140,1146],{"type":504,"tag":522,"props":1134,"children":1135},{},[1136],{"type":510,"value":1137},"路由如果被判定为 static\u002FISR",{"type":510,"value":1139},"，即便你页面里没写 ",{"type":504,"tag":656,"props":1141,"children":1143},{"className":1142},[],[1144],{"type":510,"value":1145},"revalidate",{"type":510,"value":1147},"，也可能在生产环境看到“复用\u002F延迟更新”的行为",{"type":504,"tag":534,"props":1149,"children":1150},{},[1151,1156],{"type":504,"tag":522,"props":1152,"children":1153},{},[1154],{"type":510,"value":1155},"路由被判定为 dynamic",{"type":510,"value":1157},"，很多 fetch 默认会变得更接近实时（但成本更高）",{"type":504,"tag":512,"props":1159,"children":1160},{},[1161],{"type":504,"tag":516,"props":1162,"children":1163},{},[1164,1166,1172,1173,1179],{"type":510,"value":1165},"常见触发“动态化”的因素：读取 ",{"type":504,"tag":656,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":510,"value":1171},"cookies()",{"type":510,"value":696},{"type":504,"tag":656,"props":1174,"children":1176},{"className":1175},[],[1177],{"type":510,"value":1178},"headers()",{"type":510,"value":1180},"、使用某些用户态 API 等。",{"type":504,"tag":750,"props":1182,"children":1184},{"id":1183},"_14-route-segment-cache客户端soft-navigation-为何还在看旧数据",[1185],{"type":510,"value":1186},"1.4 Route Segment Cache（客户端）：soft navigation 为何还在看旧数据",{"type":504,"tag":516,"props":1188,"children":1189},{},[1190],{"type":510,"value":1191},"App Router 在浏览器端会缓存一份“segment tree 对应的 RSC payload”。因此会出现：",{"type":504,"tag":530,"props":1193,"children":1194},{},[1195,1200,1205],{"type":504,"tag":534,"props":1196,"children":1197},{},[1198],{"type":510,"value":1199},"数据其实在服务端已更新",{"type":504,"tag":534,"props":1201,"children":1202},{},[1203],{"type":510,"value":1204},"但用户从 A → B 的站内跳转复用了旧的 RSC payload",{"type":504,"tag":534,"props":1206,"children":1207},{},[1208,1210,1216],{"type":510,"value":1209},"只有硬刷新\u002F",{"type":504,"tag":656,"props":1211,"children":1213},{"className":1212},[],[1214],{"type":510,"value":1215},"router.refresh()",{"type":510,"value":1217}," 才会看到新数据",{"type":504,"tag":516,"props":1219,"children":1220},{},[1221],{"type":510,"value":1222},"高频触发场景：",{"type":504,"tag":530,"props":1224,"children":1225},{},[1226,1237],{"type":504,"tag":534,"props":1227,"children":1228},{},[1229,1235],{"type":504,"tag":656,"props":1230,"children":1232},{"className":1231},[],[1233],{"type":510,"value":1234},"\u003CLink \u002F>",{"type":510,"value":1236}," prefetch 把旧 RSC 提前拉到本地缓存",{"type":504,"tag":534,"props":1238,"children":1239},{},[1240,1242],{"type":510,"value":1241},"mutation 发生后，你只更新了 DB，但没有触发 ",{"type":504,"tag":522,"props":1243,"children":1244},{},[1245],{"type":510,"value":1246},"refresh \u002F revalidate",{"type":504,"tag":577,"props":1248,"children":1250},{"id":1249},"_2-revalidate-的三种语义time-based-on-demand-no-store",[1251],{"type":510,"value":1252},"2. revalidate 的三种语义：time-based \u002F on-demand \u002F no-store",{"type":504,"tag":750,"props":1254,"children":1256},{"id":1255},"_21-time-based过期后再更新最终一致",[1257],{"type":510,"value":1258},"2.1 time-based：过期后再更新（“最终一致”）",{"type":504,"tag":530,"props":1260,"children":1261},{},[1262,1273],{"type":504,"tag":534,"props":1263,"children":1264},{},[1265,1271],{"type":504,"tag":656,"props":1266,"children":1268},{"className":1267},[],[1269],{"type":510,"value":1270},"revalidate: 60",{"type":510,"value":1272}," 表示：在 60 秒窗口内可能仍返回旧内容",{"type":504,"tag":534,"props":1274,"children":1275},{},[1276],{"type":510,"value":1277},"适用于：可接受延迟的公共数据（资讯、运营位、列表）",{"type":504,"tag":516,"props":1279,"children":1280},{},[1281],{"type":510,"value":1282},"常见误区：",{"type":504,"tag":530,"props":1284,"children":1285},{},[1286],{"type":504,"tag":534,"props":1287,"children":1288},{},[1289,1291,1296,1298],{"type":510,"value":1290},"以为 ",{"type":504,"tag":656,"props":1292,"children":1294},{"className":1293},[],[1295],{"type":510,"value":1270},{"type":510,"value":1297}," 是“60 秒后立刻变新”\n",{"type":504,"tag":530,"props":1299,"children":1300},{},[1301],{"type":504,"tag":534,"props":1302,"children":1303},{},[1304,1306,1311],{"type":510,"value":1305},"实际更像：",{"type":504,"tag":522,"props":1307,"children":1308},{},[1309],{"type":510,"value":1310},"60 秒后下一次请求才会触发再生成",{"type":510,"value":1312},"（且不同平台\u002FCDN 行为会影响体感）",{"type":504,"tag":750,"props":1314,"children":1316},{"id":1315},"_22-on-demand写入后立刻让读缓存失效写后读一致的工程解",[1317],{"type":510,"value":1318},"2.2 on-demand：写入后立刻让读缓存失效（“写后读一致”的工程解）",{"type":504,"tag":516,"props":1320,"children":1321},{},[1322],{"type":510,"value":1323},"核心 API：",{"type":504,"tag":530,"props":1325,"children":1326},{},[1327,1338],{"type":504,"tag":534,"props":1328,"children":1329},{},[1330,1336],{"type":504,"tag":656,"props":1331,"children":1333},{"className":1332},[],[1334],{"type":510,"value":1335},"revalidateTag(tag)",{"type":510,"value":1337},"：按“数据域”失效（推荐默认）",{"type":504,"tag":534,"props":1339,"children":1340},{},[1341,1347],{"type":504,"tag":656,"props":1342,"children":1344},{"className":1343},[],[1345],{"type":510,"value":1346},"revalidatePath(path)",{"type":510,"value":1348},"：按“路径”失效（用于路由级输出）",{"type":504,"tag":512,"props":1350,"children":1351},{},[1352],{"type":504,"tag":516,"props":1353,"children":1354},{},[1355,1357,1362],{"type":510,"value":1356},"经验：",{"type":504,"tag":522,"props":1358,"children":1359},{},[1360],{"type":510,"value":1361},"tag 更接近数据层一致性",{"type":510,"value":1363},"，path 更接近页面层一致性。",{"type":504,"tag":750,"props":1365,"children":1367},{"id":1366},"_23-no-store完全不缓存强一致但贵",[1368],{"type":510,"value":1369},"2.3 no-store：完全不缓存（“强一致但贵”）",{"type":504,"tag":530,"props":1371,"children":1372},{},[1373,1382],{"type":504,"tag":534,"props":1374,"children":1375},{},[1376],{"type":504,"tag":656,"props":1377,"children":1379},{"className":1378},[],[1380],{"type":510,"value":1381},"fetch(url, { cache: 'no-store' })",{"type":504,"tag":534,"props":1383,"children":1384},{},[1385],{"type":510,"value":1386},"适用于：用户态\u002F权限敏感\u002F强一致数据",{"type":504,"tag":516,"props":1388,"children":1389},{},[1390],{"type":510,"value":1282},{"type":504,"tag":530,"props":1392,"children":1393},{},[1394,1406],{"type":504,"tag":534,"props":1395,"children":1396},{},[1397,1399,1404],{"type":510,"value":1398},"只给某个 fetch ",{"type":504,"tag":656,"props":1400,"children":1402},{"className":1401},[],[1403],{"type":510,"value":661},{"type":510,"value":1405},"，但页面仍被 segment\u002Froute 静态化复用，导致“看起来还是旧”",{"type":504,"tag":534,"props":1407,"children":1408},{},[1409,1411,1416],{"type":510,"value":1410},"或者相反：页面是动态的，但你的数据函数用了 ",{"type":504,"tag":656,"props":1412,"children":1414},{"className":1413},[],[1415],{"type":510,"value":702},{"type":510,"value":1417},"，照样永远旧",{"type":504,"tag":577,"props":1419,"children":1421},{"id":1420},"_3-server-actions写入自动刷新读缓存",[1422],{"type":510,"value":1423},"3. Server Actions：写入≠自动刷新读缓存",{"type":504,"tag":516,"props":1425,"children":1426},{},[1427],{"type":510,"value":1428},"Server Action 更像一个“RPC 写接口”：",{"type":504,"tag":530,"props":1430,"children":1431},{},[1432,1437],{"type":504,"tag":534,"props":1433,"children":1434},{},[1435],{"type":510,"value":1436},"它会改变数据库\u002F后端状态",{"type":504,"tag":534,"props":1438,"children":1439},{},[1440,1442,1447],{"type":510,"value":1441},"但 ",{"type":504,"tag":522,"props":1443,"children":1444},{},[1445],{"type":510,"value":1446},"不会自动通知",{"type":510,"value":1448}," Next 的 Data Cache \u002F 路由输出缓存 \u002F 客户端 route cache",{"type":504,"tag":516,"props":1450,"children":1451},{},[1452],{"type":510,"value":1453},"因此 mutation 的标准收尾动作通常是：",{"type":504,"tag":584,"props":1455,"children":1456},{},[1457,1479],{"type":504,"tag":534,"props":1458,"children":1459},{},[1460,1465,1466,1472,1473],{"type":504,"tag":522,"props":1461,"children":1462},{},[1463],{"type":510,"value":1464},"服务端失效缓存",{"type":510,"value":528},{"type":504,"tag":656,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":510,"value":1471},"revalidateTag",{"type":510,"value":696},{"type":504,"tag":656,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":510,"value":1478},"revalidatePath",{"type":504,"tag":534,"props":1480,"children":1481},{},[1482,1487,1488,1493],{"type":504,"tag":522,"props":1483,"children":1484},{},[1485],{"type":510,"value":1486},"客户端刷新当前路由树",{"type":510,"value":528},{"type":504,"tag":656,"props":1489,"children":1491},{"className":1490},[],[1492],{"type":510,"value":1215},{"type":510,"value":1494},"（尤其是你留在同一页时）",{"type":504,"tag":516,"props":1496,"children":1497},{},[1498],{"type":510,"value":1499},"示例（推荐形态：tag 驱动）：",{"type":504,"tag":836,"props":1501,"children":1503},{"className":838,"code":1502,"language":840,"meta":841,"style":841},"\u002F\u002F app\u002Factions\u002FupdatePost.ts\n'use server'\n\nimport { revalidateTag } from 'next\u002Fcache'\n\nexport async function updatePostAction(id: string, input: any) {\n  await db.post.update({ where: { id }, data: input })\n\n  \u002F\u002F 失效“数据域”\n  revalidateTag(`post:${id}`)\n  revalidateTag('post:list')\n}\n",[1504],{"type":504,"tag":656,"props":1505,"children":1506},{"__ignoreMap":841},[1507,1515,1523,1530,1553,1560,1626,1649,1657,1666,1698,1719],{"type":504,"tag":847,"props":1508,"children":1509},{"class":849,"line":850},[1510],{"type":504,"tag":847,"props":1511,"children":1512},{"style":923},[1513],{"type":510,"value":1514},"\u002F\u002F app\u002Factions\u002FupdatePost.ts\n",{"type":504,"tag":847,"props":1516,"children":1517},{"class":849,"line":632},[1518],{"type":504,"tag":847,"props":1519,"children":1520},{"style":873},[1521],{"type":510,"value":1522},"'use server'\n",{"type":504,"tag":847,"props":1524,"children":1525},{"class":849,"line":666},[1526],{"type":504,"tag":847,"props":1527,"children":1528},{"emptyLinePlaceholder":1102},[1529],{"type":510,"value":1105},{"type":504,"tag":847,"props":1531,"children":1532},{"class":849,"line":903},[1533,1538,1543,1548],{"type":504,"tag":847,"props":1534,"children":1535},{"style":879},[1536],{"type":510,"value":1537},"import",{"type":504,"tag":847,"props":1539,"children":1540},{"style":859},[1541],{"type":510,"value":1542}," { revalidateTag } ",{"type":504,"tag":847,"props":1544,"children":1545},{"style":879},[1546],{"type":510,"value":1547},"from",{"type":504,"tag":847,"props":1549,"children":1550},{"style":873},[1551],{"type":510,"value":1552}," 'next\u002Fcache'\n",{"type":504,"tag":847,"props":1554,"children":1555},{"class":849,"line":929},[1556],{"type":504,"tag":847,"props":1557,"children":1558},{"emptyLinePlaceholder":1102},[1559],{"type":510,"value":1105},{"type":504,"tag":847,"props":1561,"children":1562},{"class":849,"line":963},[1563,1567,1572,1577,1582,1587,1593,1598,1603,1607,1612,1616,1621],{"type":504,"tag":847,"props":1564,"children":1565},{"style":879},[1566],{"type":510,"value":1012},{"type":504,"tag":847,"props":1568,"children":1569},{"style":879},[1570],{"type":510,"value":1571}," async",{"type":504,"tag":847,"props":1573,"children":1574},{"style":879},[1575],{"type":510,"value":1576}," function",{"type":504,"tag":847,"props":1578,"children":1579},{"style":854},[1580],{"type":510,"value":1581}," updatePostAction",{"type":504,"tag":847,"props":1583,"children":1584},{"style":859},[1585],{"type":510,"value":1586},"(",{"type":504,"tag":847,"props":1588,"children":1590},{"style":1589},"--shiki-default:#E36209;--shiki-dark:#FFAB70",[1591],{"type":510,"value":1592},"id",{"type":504,"tag":847,"props":1594,"children":1595},{"style":879},[1596],{"type":510,"value":1597},":",{"type":504,"tag":847,"props":1599,"children":1600},{"style":912},[1601],{"type":510,"value":1602}," string",{"type":504,"tag":847,"props":1604,"children":1605},{"style":859},[1606],{"type":510,"value":945},{"type":504,"tag":847,"props":1608,"children":1609},{"style":1589},[1610],{"type":510,"value":1611},"input",{"type":504,"tag":847,"props":1613,"children":1614},{"style":879},[1615],{"type":510,"value":1597},{"type":504,"tag":847,"props":1617,"children":1618},{"style":912},[1619],{"type":510,"value":1620}," any",{"type":504,"tag":847,"props":1622,"children":1623},{"style":859},[1624],{"type":510,"value":1625},") {\n",{"type":504,"tag":847,"props":1627,"children":1628},{"class":849,"line":972},[1629,1634,1639,1644],{"type":504,"tag":847,"props":1630,"children":1631},{"style":879},[1632],{"type":510,"value":1633},"  await",{"type":504,"tag":847,"props":1635,"children":1636},{"style":859},[1637],{"type":510,"value":1638}," db.post.",{"type":504,"tag":847,"props":1640,"children":1641},{"style":854},[1642],{"type":510,"value":1643},"update",{"type":504,"tag":847,"props":1645,"children":1646},{"style":859},[1647],{"type":510,"value":1648},"({ where: { id }, data: input })\n",{"type":504,"tag":847,"props":1650,"children":1652},{"class":849,"line":1651},8,[1653],{"type":504,"tag":847,"props":1654,"children":1655},{"emptyLinePlaceholder":1102},[1656],{"type":510,"value":1105},{"type":504,"tag":847,"props":1658,"children":1660},{"class":849,"line":1659},9,[1661],{"type":504,"tag":847,"props":1662,"children":1663},{"style":923},[1664],{"type":510,"value":1665},"  \u002F\u002F 失效“数据域”\n",{"type":504,"tag":847,"props":1667,"children":1669},{"class":849,"line":1668},10,[1670,1675,1679,1684,1688,1693],{"type":504,"tag":847,"props":1671,"children":1672},{"style":854},[1673],{"type":510,"value":1674},"  revalidateTag",{"type":504,"tag":847,"props":1676,"children":1677},{"style":859},[1678],{"type":510,"value":1586},{"type":504,"tag":847,"props":1680,"children":1681},{"style":873},[1682],{"type":510,"value":1683},"`post:${",{"type":504,"tag":847,"props":1685,"children":1686},{"style":859},[1687],{"type":510,"value":1592},{"type":504,"tag":847,"props":1689,"children":1690},{"style":873},[1691],{"type":510,"value":1692},"}`",{"type":504,"tag":847,"props":1694,"children":1695},{"style":859},[1696],{"type":510,"value":1697},")\n",{"type":504,"tag":847,"props":1699,"children":1701},{"class":849,"line":1700},11,[1702,1706,1710,1715],{"type":504,"tag":847,"props":1703,"children":1704},{"style":854},[1705],{"type":510,"value":1674},{"type":504,"tag":847,"props":1707,"children":1708},{"style":859},[1709],{"type":510,"value":1586},{"type":504,"tag":847,"props":1711,"children":1712},{"style":873},[1713],{"type":510,"value":1714},"'post:list'",{"type":504,"tag":847,"props":1716,"children":1717},{"style":859},[1718],{"type":510,"value":1697},{"type":504,"tag":847,"props":1720,"children":1722},{"class":849,"line":1721},12,[1723],{"type":504,"tag":847,"props":1724,"children":1725},{"style":859},[1726],{"type":510,"value":1727},"}\n",{"type":504,"tag":516,"props":1729,"children":1730},{},[1731],{"type":510,"value":1732},"读路径：",{"type":504,"tag":836,"props":1734,"children":1736},{"className":838,"code":1735,"language":840,"meta":841,"style":841},"export async function getPost(id: string) {\n  const res = await fetch(`${API}\u002Fposts\u002F${id}`, {\n    next: { tags: [`post:${id}`], revalidate: 300 },\n  })\n  return res.json()\n}\n",[1737],{"type":504,"tag":656,"props":1738,"children":1739},{"__ignoreMap":841},[1740,1780,1839,1874,1882,1905],{"type":504,"tag":847,"props":1741,"children":1742},{"class":849,"line":850},[1743,1747,1751,1755,1760,1764,1768,1772,1776],{"type":504,"tag":847,"props":1744,"children":1745},{"style":879},[1746],{"type":510,"value":1012},{"type":504,"tag":847,"props":1748,"children":1749},{"style":879},[1750],{"type":510,"value":1571},{"type":504,"tag":847,"props":1752,"children":1753},{"style":879},[1754],{"type":510,"value":1576},{"type":504,"tag":847,"props":1756,"children":1757},{"style":854},[1758],{"type":510,"value":1759}," getPost",{"type":504,"tag":847,"props":1761,"children":1762},{"style":859},[1763],{"type":510,"value":1586},{"type":504,"tag":847,"props":1765,"children":1766},{"style":1589},[1767],{"type":510,"value":1592},{"type":504,"tag":847,"props":1769,"children":1770},{"style":879},[1771],{"type":510,"value":1597},{"type":504,"tag":847,"props":1773,"children":1774},{"style":912},[1775],{"type":510,"value":1602},{"type":504,"tag":847,"props":1777,"children":1778},{"style":859},[1779],{"type":510,"value":1625},{"type":504,"tag":847,"props":1781,"children":1782},{"class":849,"line":632},[1783,1788,1793,1797,1802,1807,1811,1816,1821,1826,1830,1834],{"type":504,"tag":847,"props":1784,"children":1785},{"style":879},[1786],{"type":510,"value":1787},"  const",{"type":504,"tag":847,"props":1789,"children":1790},{"style":912},[1791],{"type":510,"value":1792}," res",{"type":504,"tag":847,"props":1794,"children":1795},{"style":879},[1796],{"type":510,"value":1027},{"type":504,"tag":847,"props":1798,"children":1799},{"style":879},[1800],{"type":510,"value":1801}," await",{"type":504,"tag":847,"props":1803,"children":1804},{"style":854},[1805],{"type":510,"value":1806}," fetch",{"type":504,"tag":847,"props":1808,"children":1809},{"style":859},[1810],{"type":510,"value":1586},{"type":504,"tag":847,"props":1812,"children":1813},{"style":873},[1814],{"type":510,"value":1815},"`${",{"type":504,"tag":847,"props":1817,"children":1818},{"style":912},[1819],{"type":510,"value":1820},"API",{"type":504,"tag":847,"props":1822,"children":1823},{"style":873},[1824],{"type":510,"value":1825},"}\u002Fposts\u002F${",{"type":504,"tag":847,"props":1827,"children":1828},{"style":859},[1829],{"type":510,"value":1592},{"type":504,"tag":847,"props":1831,"children":1832},{"style":873},[1833],{"type":510,"value":1692},{"type":504,"tag":847,"props":1835,"children":1836},{"style":859},[1837],{"type":510,"value":1838},", {\n",{"type":504,"tag":847,"props":1840,"children":1841},{"class":849,"line":666},[1842,1847,1851,1855,1859,1864,1869],{"type":504,"tag":847,"props":1843,"children":1844},{"style":859},[1845],{"type":510,"value":1846},"    next: { tags: [",{"type":504,"tag":847,"props":1848,"children":1849},{"style":873},[1850],{"type":510,"value":1683},{"type":504,"tag":847,"props":1852,"children":1853},{"style":859},[1854],{"type":510,"value":1592},{"type":504,"tag":847,"props":1856,"children":1857},{"style":873},[1858],{"type":510,"value":1692},{"type":504,"tag":847,"props":1860,"children":1861},{"style":859},[1862],{"type":510,"value":1863},"], revalidate: ",{"type":504,"tag":847,"props":1865,"children":1866},{"style":912},[1867],{"type":510,"value":1868},"300",{"type":504,"tag":847,"props":1870,"children":1871},{"style":859},[1872],{"type":510,"value":1873}," },\n",{"type":504,"tag":847,"props":1875,"children":1876},{"class":849,"line":903},[1877],{"type":504,"tag":847,"props":1878,"children":1879},{"style":859},[1880],{"type":510,"value":1881},"  })\n",{"type":504,"tag":847,"props":1883,"children":1884},{"class":849,"line":929},[1885,1890,1895,1900],{"type":504,"tag":847,"props":1886,"children":1887},{"style":879},[1888],{"type":510,"value":1889},"  return",{"type":504,"tag":847,"props":1891,"children":1892},{"style":859},[1893],{"type":510,"value":1894}," res.",{"type":504,"tag":847,"props":1896,"children":1897},{"style":854},[1898],{"type":510,"value":1899},"json",{"type":504,"tag":847,"props":1901,"children":1902},{"style":859},[1903],{"type":510,"value":1904},"()\n",{"type":504,"tag":847,"props":1906,"children":1907},{"class":849,"line":963},[1908],{"type":504,"tag":847,"props":1909,"children":1910},{"style":859},[1911],{"type":510,"value":1727},{"type":504,"tag":516,"props":1913,"children":1914},{},[1915],{"type":510,"value":1916},"留在同页的交互（客户端）：",{"type":504,"tag":836,"props":1918,"children":1920},{"className":838,"code":1919,"language":840,"meta":841,"style":841},"import { useRouter } from 'next\u002Fnavigation'\n\nconst router = useRouter()\n\nawait updatePostAction(id, input)\nrouter.refresh() \u002F\u002F 刷新 segment tree（避免命中本地旧 RSC payload）\n",[1921],{"type":504,"tag":656,"props":1922,"children":1923},{"__ignoreMap":841},[1924,1945,1952,1978,1985,2002],{"type":504,"tag":847,"props":1925,"children":1926},{"class":849,"line":850},[1927,1931,1936,1940],{"type":504,"tag":847,"props":1928,"children":1929},{"style":879},[1930],{"type":510,"value":1537},{"type":504,"tag":847,"props":1932,"children":1933},{"style":859},[1934],{"type":510,"value":1935}," { useRouter } ",{"type":504,"tag":847,"props":1937,"children":1938},{"style":879},[1939],{"type":510,"value":1547},{"type":504,"tag":847,"props":1941,"children":1942},{"style":873},[1943],{"type":510,"value":1944}," 'next\u002Fnavigation'\n",{"type":504,"tag":847,"props":1946,"children":1947},{"class":849,"line":632},[1948],{"type":504,"tag":847,"props":1949,"children":1950},{"emptyLinePlaceholder":1102},[1951],{"type":510,"value":1105},{"type":504,"tag":847,"props":1953,"children":1954},{"class":849,"line":666},[1955,1960,1965,1969,1974],{"type":504,"tag":847,"props":1956,"children":1957},{"style":879},[1958],{"type":510,"value":1959},"const",{"type":504,"tag":847,"props":1961,"children":1962},{"style":912},[1963],{"type":510,"value":1964}," router",{"type":504,"tag":847,"props":1966,"children":1967},{"style":879},[1968],{"type":510,"value":1027},{"type":504,"tag":847,"props":1970,"children":1971},{"style":854},[1972],{"type":510,"value":1973}," useRouter",{"type":504,"tag":847,"props":1975,"children":1976},{"style":859},[1977],{"type":510,"value":1904},{"type":504,"tag":847,"props":1979,"children":1980},{"class":849,"line":903},[1981],{"type":504,"tag":847,"props":1982,"children":1983},{"emptyLinePlaceholder":1102},[1984],{"type":510,"value":1105},{"type":504,"tag":847,"props":1986,"children":1987},{"class":849,"line":929},[1988,1993,1997],{"type":504,"tag":847,"props":1989,"children":1990},{"style":879},[1991],{"type":510,"value":1992},"await",{"type":504,"tag":847,"props":1994,"children":1995},{"style":854},[1996],{"type":510,"value":1581},{"type":504,"tag":847,"props":1998,"children":1999},{"style":859},[2000],{"type":510,"value":2001},"(id, input)\n",{"type":504,"tag":847,"props":2003,"children":2004},{"class":849,"line":963},[2005,2010,2015,2020],{"type":504,"tag":847,"props":2006,"children":2007},{"style":859},[2008],{"type":510,"value":2009},"router.",{"type":504,"tag":847,"props":2011,"children":2012},{"style":854},[2013],{"type":510,"value":2014},"refresh",{"type":504,"tag":847,"props":2016,"children":2017},{"style":859},[2018],{"type":510,"value":2019},"() ",{"type":504,"tag":847,"props":2021,"children":2022},{"style":923},[2023],{"type":510,"value":2024},"\u002F\u002F 刷新 segment tree（避免命中本地旧 RSC payload）\n",{"type":504,"tag":577,"props":2026,"children":2028},{"id":2027},"_4-常见坑位清单为什么线上不更新",[2029],{"type":510,"value":2030},"4. 常见坑位清单（“为什么线上不更新”）",{"type":504,"tag":750,"props":2032,"children":2034},{"id":2033},"_41-本地-dev-没问题线上才复现",[2035],{"type":510,"value":2036},"4.1 本地 dev 没问题，线上才复现",{"type":504,"tag":530,"props":2038,"children":2039},{},[2040,2051],{"type":504,"tag":534,"props":2041,"children":2042},{},[2043,2049],{"type":504,"tag":656,"props":2044,"children":2046},{"className":2045},[],[2047],{"type":510,"value":2048},"next dev",{"type":510,"value":2050}," 的缓存策略与 production 不同（更偏“开发体验”）",{"type":504,"tag":534,"props":2052,"children":2053},{},[2054],{"type":510,"value":2055},"线上才会出现：Full Route Cache \u002F Data Cache \u002F CDN 缓存 \u002F prefetch",{"type":504,"tag":516,"props":2057,"children":2058},{},[2059,2064,2066,2072],{"type":504,"tag":522,"props":2060,"children":2061},{},[2062],{"type":510,"value":2063},"排查要求",{"type":510,"value":2065},"：用 ",{"type":504,"tag":656,"props":2067,"children":2069},{"className":2068},[],[2070],{"type":510,"value":2071},"next build && next start",{"type":510,"value":2073}," 复现，或在预发用同样部署形态。",{"type":504,"tag":750,"props":2075,"children":2077},{"id":2076},"_42-以为-fetch-默认实时实际被-data-cache-复用",[2078,2080,2085],{"type":510,"value":2079},"4.2 以为 ",{"type":504,"tag":656,"props":2081,"children":2083},{"className":2082},[],[2084],{"type":510,"value":694},{"type":510,"value":2086}," 默认实时，实际被 Data Cache 复用",{"type":504,"tag":530,"props":2088,"children":2089},{},[2090,2102],{"type":504,"tag":534,"props":2091,"children":2092},{},[2093,2095,2100],{"type":510,"value":2094},"在 static\u002FISR route 下，",{"type":504,"tag":656,"props":2096,"children":2098},{"className":2097},[],[2099],{"type":510,"value":694},{"type":510,"value":2101}," 很容易进入 cache",{"type":504,"tag":534,"props":2103,"children":2104},{},[2105],{"type":510,"value":2106},"你看日志会发现“函数没重新跑\u002F接口没重新请求”",{"type":504,"tag":516,"props":2108,"children":2109},{},[2110],{"type":510,"value":2111},"解决：",{"type":504,"tag":530,"props":2113,"children":2114},{},[2115,2134],{"type":504,"tag":534,"props":2116,"children":2117},{},[2118,2120,2126,2128],{"type":510,"value":2119},"明确写出策略：",{"type":504,"tag":656,"props":2121,"children":2123},{"className":2122},[],[2124],{"type":510,"value":2125},"cache: 'no-store'",{"type":510,"value":2127}," 或 ",{"type":504,"tag":656,"props":2129,"children":2131},{"className":2130},[],[2132],{"type":510,"value":2133},"next: { revalidate, tags }",{"type":504,"tag":534,"props":2135,"children":2136},{},[2137],{"type":510,"value":2138},"把策略收敛到数据层函数（不要散落到页面里）",{"type":504,"tag":750,"props":2140,"children":2142},{"id":2141},"_43-用了-revalidatepath但数据被多个路由复用",[2143,2145,2150],{"type":510,"value":2144},"4.3 用了 ",{"type":504,"tag":656,"props":2146,"children":2148},{"className":2147},[],[2149],{"type":510,"value":1478},{"type":510,"value":2151},"，但数据被多个路由复用",{"type":504,"tag":530,"props":2153,"children":2154},{},[2155],{"type":504,"tag":534,"props":2156,"children":2157},{},[2158,2160,2166,2168,2174],{"type":510,"value":2159},"你失效了 ",{"type":504,"tag":656,"props":2161,"children":2163},{"className":2162},[],[2164],{"type":510,"value":2165},"\u002Fposts\u002F123",{"type":510,"value":2167},"，但列表页 ",{"type":504,"tag":656,"props":2169,"children":2171},{"className":2170},[],[2172],{"type":510,"value":2173},"\u002Fposts",{"type":510,"value":2175}," 仍复用旧缓存",{"type":504,"tag":516,"props":2177,"children":2178},{},[2179],{"type":510,"value":2111},{"type":504,"tag":530,"props":2181,"children":2182},{},[2183],{"type":504,"tag":534,"props":2184,"children":2185},{},[2186,2188,2194],{"type":510,"value":2187},"用 ",{"type":504,"tag":656,"props":2189,"children":2191},{"className":2190},[],[2192],{"type":510,"value":2193},"revalidateTag('post:list')",{"type":510,"value":2195}," 一次性失效所有依赖该数据域的路由",{"type":504,"tag":750,"props":2197,"children":2199},{"id":2198},"_44-soft-navigation-命中-route-segment-cache硬刷新才更新",[2200],{"type":510,"value":2201},"4.4 soft navigation 命中 Route Segment Cache：硬刷新才更新",{"type":504,"tag":516,"props":2203,"children":2204},{},[2205],{"type":510,"value":2206},"表现：",{"type":504,"tag":530,"props":2208,"children":2209},{},[2210,2215],{"type":504,"tag":534,"props":2211,"children":2212},{},[2213],{"type":510,"value":2214},"用户从站内点链接看到旧内容",{"type":504,"tag":534,"props":2216,"children":2217},{},[2218,2224],{"type":504,"tag":656,"props":2219,"children":2221},{"className":2220},[],[2222],{"type":510,"value":2223},"Cmd+R",{"type":510,"value":2225},"\u002F强刷后变新",{"type":504,"tag":516,"props":2227,"children":2228},{},[2229],{"type":510,"value":2111},{"type":504,"tag":530,"props":2231,"children":2232},{},[2233,2245,2258],{"type":504,"tag":534,"props":2234,"children":2235},{},[2236,2238,2243],{"type":510,"value":2237},"mutation 后 ",{"type":504,"tag":656,"props":2239,"children":2241},{"className":2240},[],[2242],{"type":510,"value":1215},{"type":510,"value":2244},"（留在同页）",{"type":504,"tag":534,"props":2246,"children":2247},{},[2248,2250,2256],{"type":510,"value":2249},"或者 mutation 后 ",{"type":504,"tag":656,"props":2251,"children":2253},{"className":2252},[],[2254],{"type":510,"value":2255},"redirect()",{"type":510,"value":2257}," 到目标页（导航会触发新的 RSC 请求，但仍建议配合 revalidate）",{"type":504,"tag":534,"props":2259,"children":2260},{},[2261],{"type":510,"value":2262},"对“强一致页面”，谨慎 prefetch（或评估是否需要）",{"type":504,"tag":750,"props":2264,"children":2266},{"id":2265},"_45-unstable_cache自定义缓存失效体系缺失",[2267,2269,2274],{"type":510,"value":2268},"4.5 ",{"type":504,"tag":656,"props":2270,"children":2272},{"className":2271},[],[2273],{"type":510,"value":702},{"type":510,"value":2275},"\u002F自定义缓存：失效体系缺失",{"type":504,"tag":530,"props":2277,"children":2278},{},[2279,2291],{"type":504,"tag":534,"props":2280,"children":2281},{},[2282,2284,2289],{"type":510,"value":2283},"DB 直连、SDK 调用不是 fetch（不会自动进入 Data Cache），你可能用了 ",{"type":504,"tag":656,"props":2285,"children":2287},{"className":2286},[],[2288],{"type":510,"value":702},{"type":510,"value":2290}," 包了一层",{"type":504,"tag":534,"props":2292,"children":2293},{},[2294],{"type":510,"value":2295},"一旦没有 tags \u002F revalidate，就会永久旧",{"type":504,"tag":516,"props":2297,"children":2298},{},[2299],{"type":510,"value":2111},{"type":504,"tag":530,"props":2301,"children":2302},{},[2303,2315],{"type":504,"tag":534,"props":2304,"children":2305},{},[2306,2308,2313],{"type":510,"value":2307},"给 ",{"type":504,"tag":656,"props":2309,"children":2311},{"className":2310},[],[2312],{"type":510,"value":702},{"type":510,"value":2314}," 明确 tags",{"type":504,"tag":534,"props":2316,"children":2317},{},[2318,2320],{"type":510,"value":2319},"或者对强一致域禁止 ",{"type":504,"tag":656,"props":2321,"children":2323},{"className":2322},[],[2324],{"type":510,"value":702},{"type":504,"tag":750,"props":2326,"children":2328},{"id":2327},"_46-双缓存真相next-缓存-client-query-缓存",[2329],{"type":510,"value":2330},"4.6 双缓存真相：Next 缓存 + Client Query 缓存",{"type":504,"tag":530,"props":2332,"children":2333},{},[2334,2339],{"type":504,"tag":534,"props":2335,"children":2336},{},[2337],{"type":510,"value":2338},"RSC 用 Next cache，Client 组件又用 TanStack Query 管同一份数据",{"type":504,"tag":534,"props":2340,"children":2341},{},[2342],{"type":510,"value":2343},"你 invalidate 了 A，却忘了 invalidate B",{"type":504,"tag":516,"props":2345,"children":2346},{},[2347],{"type":510,"value":2111},{"type":504,"tag":530,"props":2349,"children":2350},{},[2351],{"type":504,"tag":534,"props":2352,"children":2353},{},[2354,2356],{"type":510,"value":2355},"“同一数据域只选一套真相”：\n",{"type":504,"tag":530,"props":2357,"children":2358},{},[2359,2364],{"type":504,"tag":534,"props":2360,"children":2361},{},[2362],{"type":510,"value":2363},"页面级\u002F首屏：RSC + Next cache",{"type":504,"tag":534,"props":2365,"children":2366},{},[2367,2369,2375],{"type":510,"value":2368},"强交互：Client Query（并用 ",{"type":504,"tag":656,"props":2370,"children":2372},{"className":2371},[],[2373],{"type":510,"value":2374},"router.refresh",{"type":510,"value":2376}," 仅做壳更新）",{"type":504,"tag":577,"props":2378,"children":2380},{"id":2379},"_5-debugging-checklist可直接拷贝到-issue",[2381],{"type":510,"value":2382},"5. Debugging Checklist（可直接拷贝到 issue）",{"type":504,"tag":750,"props":2384,"children":2386},{"id":2385},"_51-复现条件",[2387],{"type":510,"value":2388},"5.1 复现条件",{"type":504,"tag":530,"props":2390,"children":2393},{"className":2391},[2392],"contains-task-list",[2394,2412,2421],{"type":504,"tag":534,"props":2395,"children":2398},{"className":2396},[2397],"task-list-item",[2399,2403,2405,2410],{"type":504,"tag":1611,"props":2400,"children":2402},{"disabled":1102,"type":2401},"checkbox",[],{"type":510,"value":2404}," 是否在 production build 复现？（",{"type":504,"tag":656,"props":2406,"children":2408},{"className":2407},[],[2409],{"type":510,"value":2071},{"type":510,"value":2411},"）",{"type":504,"tag":534,"props":2413,"children":2415},{"className":2414},[2397],[2416,2419],{"type":504,"tag":1611,"props":2417,"children":2418},{"disabled":1102,"type":2401},[],{"type":510,"value":2420}," 是否只在站内跳转复现？硬刷新是否能变新？",{"type":504,"tag":534,"props":2422,"children":2424},{"className":2423},[2397],[2425,2428],{"type":504,"tag":1611,"props":2426,"children":2427},{"disabled":1102,"type":2401},[],{"type":510,"value":2429}," 是否与特定用户\u002F权限\u002Fcookie 有关？（不同用户是否不同）",{"type":504,"tag":750,"props":2431,"children":2433},{"id":2432},"_52-判断是读缓存旧还是写没成功",[2434],{"type":510,"value":2435},"5.2 判断是“读缓存旧”还是“写没成功”",{"type":504,"tag":530,"props":2437,"children":2439},{"className":2438},[2392],[2440,2449],{"type":504,"tag":534,"props":2441,"children":2443},{"className":2442},[2397],[2444,2447],{"type":504,"tag":1611,"props":2445,"children":2446},{"disabled":1102,"type":2401},[],{"type":510,"value":2448}," DB\u002F后端是否确实已写入？（后台查库\u002F查日志）",{"type":504,"tag":534,"props":2450,"children":2452},{"className":2451},[2397],[2453,2456],{"type":504,"tag":1611,"props":2454,"children":2455},{"disabled":1102,"type":2401},[],{"type":510,"value":2457}," 服务端直接请求同一数据接口是否已返回新数据？（curl\u002F日志）",{"type":504,"tag":750,"props":2459,"children":2461},{"id":2460},"_53-检查读路径fetch-数据函数",[2462],{"type":510,"value":2463},"5.3 检查读路径（fetch \u002F 数据函数）",{"type":504,"tag":530,"props":2465,"children":2467},{"className":2466},[2392],[2468,2507,2523],{"type":504,"tag":534,"props":2469,"children":2471},{"className":2470},[2397],[2472,2475,2477,2482,2484,2490,2492,2498,2499,2505],{"type":504,"tag":1611,"props":2473,"children":2474},{"disabled":1102,"type":2401},[],{"type":510,"value":2476}," 关键 ",{"type":504,"tag":656,"props":2478,"children":2480},{"className":2479},[],[2481],{"type":510,"value":694},{"type":510,"value":2483}," 是否显式声明了 ",{"type":504,"tag":656,"props":2485,"children":2487},{"className":2486},[],[2488],{"type":510,"value":2489},"cache",{"type":510,"value":2491},"\u002F",{"type":504,"tag":656,"props":2493,"children":2495},{"className":2494},[],[2496],{"type":510,"value":2497},"next.revalidate",{"type":510,"value":2491},{"type":504,"tag":656,"props":2500,"children":2502},{"className":2501},[],[2503],{"type":510,"value":2504},"next.tags",{"type":510,"value":2506},"？",{"type":504,"tag":534,"props":2508,"children":2510},{"className":2509},[2397],[2511,2514,2516,2521],{"type":504,"tag":1611,"props":2512,"children":2513},{"disabled":1102,"type":2401},[],{"type":510,"value":2515}," 是否用了 ",{"type":504,"tag":656,"props":2517,"children":2519},{"className":2518},[],[2520],{"type":510,"value":702},{"type":510,"value":2522}," \u002F 自研缓存？是否有 tags\u002F失效？",{"type":504,"tag":534,"props":2524,"children":2526},{"className":2525},[2397],[2527,2530,2532,2538],{"type":504,"tag":1611,"props":2528,"children":2529},{"disabled":1102,"type":2401},[],{"type":510,"value":2531}," 是否因为 ",{"type":504,"tag":656,"props":2533,"children":2535},{"className":2534},[],[2536],{"type":510,"value":2537},"cookies()\u002Fheaders()",{"type":510,"value":2539}," 导致 segment dynamic 化（或反过来导致静态化）？",{"type":504,"tag":750,"props":2541,"children":2543},{"id":2542},"_54-检查写路径server-action-api",[2544],{"type":510,"value":2545},"5.4 检查写路径（Server Action \u002F API）",{"type":504,"tag":530,"props":2547,"children":2549},{"className":2548},[2392],[2550,2572,2587],{"type":504,"tag":534,"props":2551,"children":2553},{"className":2552},[2397],[2554,2557,2559,2564,2565,2570],{"type":504,"tag":1611,"props":2555,"children":2556},{"disabled":1102,"type":2401},[],{"type":510,"value":2558}," mutation 后是否调用 ",{"type":504,"tag":656,"props":2560,"children":2562},{"className":2561},[],[2563],{"type":510,"value":1471},{"type":510,"value":696},{"type":504,"tag":656,"props":2566,"children":2568},{"className":2567},[],[2569],{"type":510,"value":1478},{"type":510,"value":2571},"？失效粒度是否覆盖所有读页面？",{"type":504,"tag":534,"props":2573,"children":2575},{"className":2574},[2397],[2576,2579,2581,2586],{"type":504,"tag":1611,"props":2577,"children":2578},{"disabled":1102,"type":2401},[],{"type":510,"value":2580}," 留在同页是否调用 ",{"type":504,"tag":656,"props":2582,"children":2584},{"className":2583},[],[2585],{"type":510,"value":1215},{"type":510,"value":2506},{"type":504,"tag":534,"props":2588,"children":2590},{"className":2589},[2397],[2591,2594],{"type":504,"tag":1611,"props":2592,"children":2593},{"disabled":1102,"type":2401},[],{"type":510,"value":2595}," 是否存在“写后立刻读”的流程（需要强一致）？如果是，是否仍在用 time-based revalidate？",{"type":504,"tag":750,"props":2597,"children":2599},{"id":2598},"_55-检查客户端导航",[2600],{"type":510,"value":2601},"5.5 检查客户端导航",{"type":504,"tag":530,"props":2603,"children":2605},{"className":2604},[2392],[2606,2623],{"type":504,"tag":534,"props":2607,"children":2609},{"className":2608},[2397],[2610,2613,2615,2621],{"type":504,"tag":1611,"props":2611,"children":2612},{"disabled":1102,"type":2401},[],{"type":510,"value":2614}," ",{"type":504,"tag":656,"props":2616,"children":2618},{"className":2617},[],[2619],{"type":510,"value":2620},"\u003CLink prefetch>",{"type":510,"value":2622}," 是否提前拉了旧 payload？",{"type":504,"tag":534,"props":2624,"children":2626},{"className":2625},[2397],[2627,2630],{"type":504,"tag":1611,"props":2628,"children":2629},{"disabled":1102,"type":2401},[],{"type":510,"value":2631}," 是否在同一个 tab 里长期停留导致一直复用旧 segment cache？",{"type":504,"tag":577,"props":2633,"children":2635},{"id":2634},"_6-推荐模式团队级约束",[2636],{"type":510,"value":2637},"6. 推荐模式（团队级约束）",{"type":504,"tag":750,"props":2639,"children":2641},{"id":2640},"_61-缓存策略下沉到数据层",[2642],{"type":510,"value":2643},"6.1 “缓存策略下沉到数据层”",{"type":504,"tag":516,"props":2645,"children":2646},{},[2647],{"type":510,"value":2648},"不要在页面里零散写：",{"type":504,"tag":836,"props":2650,"children":2652},{"className":838,"code":2651,"language":840,"meta":841,"style":841},"\u002F\u002F ❌ 到处散落、难审计\nawait fetch(url, { next: { revalidate: 60 } })\n",[2653],{"type":504,"tag":656,"props":2654,"children":2655},{"__ignoreMap":841},[2656,2664],{"type":504,"tag":847,"props":2657,"children":2658},{"class":849,"line":850},[2659],{"type":504,"tag":847,"props":2660,"children":2661},{"style":923},[2662],{"type":510,"value":2663},"\u002F\u002F ❌ 到处散落、难审计\n",{"type":504,"tag":847,"props":2665,"children":2666},{"class":849,"line":632},[2667,2671,2675,2680,2684],{"type":504,"tag":847,"props":2668,"children":2669},{"style":879},[2670],{"type":510,"value":1992},{"type":504,"tag":847,"props":2672,"children":2673},{"style":854},[2674],{"type":510,"value":1806},{"type":504,"tag":847,"props":2676,"children":2677},{"style":859},[2678],{"type":510,"value":2679},"(url, { next: { revalidate: ",{"type":504,"tag":847,"props":2681,"children":2682},{"style":912},[2683],{"type":510,"value":915},{"type":504,"tag":847,"props":2685,"children":2686},{"style":859},[2687],{"type":510,"value":2688}," } })\n",{"type":504,"tag":516,"props":2690,"children":2691},{},[2692],{"type":510,"value":2693},"建议统一成：",{"type":504,"tag":836,"props":2695,"children":2697},{"className":838,"code":2696,"language":840,"meta":841,"style":841},"\u002F\u002F ✅ 数据层收口\nexport const tags = {\n  post: (id: string) => `post:${id}`,\n  postList: () => 'post:list',\n}\n\nexport async function getPost(id: string) {\n  return fetch(`${API}\u002Fposts\u002F${id}`, {\n    next: { tags: [tags.post(id)], revalidate: 300 },\n  }).then(r => r.json())\n}\n",[2698],{"type":504,"tag":656,"props":2699,"children":2700},{"__ignoreMap":841},[2701,2709,2734,2786,2812,2819,2826,2865,2904,2930,2971],{"type":504,"tag":847,"props":2702,"children":2703},{"class":849,"line":850},[2704],{"type":504,"tag":847,"props":2705,"children":2706},{"style":923},[2707],{"type":510,"value":2708},"\u002F\u002F ✅ 数据层收口\n",{"type":504,"tag":847,"props":2710,"children":2711},{"class":849,"line":632},[2712,2716,2720,2725,2729],{"type":504,"tag":847,"props":2713,"children":2714},{"style":879},[2715],{"type":510,"value":1012},{"type":504,"tag":847,"props":2717,"children":2718},{"style":879},[2719],{"type":510,"value":1017},{"type":504,"tag":847,"props":2721,"children":2722},{"style":912},[2723],{"type":510,"value":2724}," tags",{"type":504,"tag":847,"props":2726,"children":2727},{"style":879},[2728],{"type":510,"value":1027},{"type":504,"tag":847,"props":2730,"children":2731},{"style":859},[2732],{"type":510,"value":2733}," {\n",{"type":504,"tag":847,"props":2735,"children":2736},{"class":849,"line":666},[2737,2742,2747,2751,2755,2759,2764,2769,2774,2778,2782],{"type":504,"tag":847,"props":2738,"children":2739},{"style":854},[2740],{"type":510,"value":2741},"  post",{"type":504,"tag":847,"props":2743,"children":2744},{"style":859},[2745],{"type":510,"value":2746},": (",{"type":504,"tag":847,"props":2748,"children":2749},{"style":1589},[2750],{"type":510,"value":1592},{"type":504,"tag":847,"props":2752,"children":2753},{"style":879},[2754],{"type":510,"value":1597},{"type":504,"tag":847,"props":2756,"children":2757},{"style":912},[2758],{"type":510,"value":1602},{"type":504,"tag":847,"props":2760,"children":2761},{"style":859},[2762],{"type":510,"value":2763},") ",{"type":504,"tag":847,"props":2765,"children":2766},{"style":879},[2767],{"type":510,"value":2768},"=>",{"type":504,"tag":847,"props":2770,"children":2771},{"style":873},[2772],{"type":510,"value":2773}," `post:${",{"type":504,"tag":847,"props":2775,"children":2776},{"style":859},[2777],{"type":510,"value":1592},{"type":504,"tag":847,"props":2779,"children":2780},{"style":873},[2781],{"type":510,"value":1692},{"type":504,"tag":847,"props":2783,"children":2784},{"style":859},[2785],{"type":510,"value":892},{"type":504,"tag":847,"props":2787,"children":2788},{"class":849,"line":903},[2789,2794,2799,2803,2808],{"type":504,"tag":847,"props":2790,"children":2791},{"style":854},[2792],{"type":510,"value":2793},"  postList",{"type":504,"tag":847,"props":2795,"children":2796},{"style":859},[2797],{"type":510,"value":2798},": () ",{"type":504,"tag":847,"props":2800,"children":2801},{"style":879},[2802],{"type":510,"value":2768},{"type":504,"tag":847,"props":2804,"children":2805},{"style":873},[2806],{"type":510,"value":2807}," 'post:list'",{"type":504,"tag":847,"props":2809,"children":2810},{"style":859},[2811],{"type":510,"value":892},{"type":504,"tag":847,"props":2813,"children":2814},{"class":849,"line":929},[2815],{"type":504,"tag":847,"props":2816,"children":2817},{"style":859},[2818],{"type":510,"value":1727},{"type":504,"tag":847,"props":2820,"children":2821},{"class":849,"line":963},[2822],{"type":504,"tag":847,"props":2823,"children":2824},{"emptyLinePlaceholder":1102},[2825],{"type":510,"value":1105},{"type":504,"tag":847,"props":2827,"children":2828},{"class":849,"line":972},[2829,2833,2837,2841,2845,2849,2853,2857,2861],{"type":504,"tag":847,"props":2830,"children":2831},{"style":879},[2832],{"type":510,"value":1012},{"type":504,"tag":847,"props":2834,"children":2835},{"style":879},[2836],{"type":510,"value":1571},{"type":504,"tag":847,"props":2838,"children":2839},{"style":879},[2840],{"type":510,"value":1576},{"type":504,"tag":847,"props":2842,"children":2843},{"style":854},[2844],{"type":510,"value":1759},{"type":504,"tag":847,"props":2846,"children":2847},{"style":859},[2848],{"type":510,"value":1586},{"type":504,"tag":847,"props":2850,"children":2851},{"style":1589},[2852],{"type":510,"value":1592},{"type":504,"tag":847,"props":2854,"children":2855},{"style":879},[2856],{"type":510,"value":1597},{"type":504,"tag":847,"props":2858,"children":2859},{"style":912},[2860],{"type":510,"value":1602},{"type":504,"tag":847,"props":2862,"children":2863},{"style":859},[2864],{"type":510,"value":1625},{"type":504,"tag":847,"props":2866,"children":2867},{"class":849,"line":1651},[2868,2872,2876,2880,2884,2888,2892,2896,2900],{"type":504,"tag":847,"props":2869,"children":2870},{"style":879},[2871],{"type":510,"value":1889},{"type":504,"tag":847,"props":2873,"children":2874},{"style":854},[2875],{"type":510,"value":1806},{"type":504,"tag":847,"props":2877,"children":2878},{"style":859},[2879],{"type":510,"value":1586},{"type":504,"tag":847,"props":2881,"children":2882},{"style":873},[2883],{"type":510,"value":1815},{"type":504,"tag":847,"props":2885,"children":2886},{"style":912},[2887],{"type":510,"value":1820},{"type":504,"tag":847,"props":2889,"children":2890},{"style":873},[2891],{"type":510,"value":1825},{"type":504,"tag":847,"props":2893,"children":2894},{"style":859},[2895],{"type":510,"value":1592},{"type":504,"tag":847,"props":2897,"children":2898},{"style":873},[2899],{"type":510,"value":1692},{"type":504,"tag":847,"props":2901,"children":2902},{"style":859},[2903],{"type":510,"value":1838},{"type":504,"tag":847,"props":2905,"children":2906},{"class":849,"line":1659},[2907,2912,2917,2922,2926],{"type":504,"tag":847,"props":2908,"children":2909},{"style":859},[2910],{"type":510,"value":2911},"    next: { tags: [tags.",{"type":504,"tag":847,"props":2913,"children":2914},{"style":854},[2915],{"type":510,"value":2916},"post",{"type":504,"tag":847,"props":2918,"children":2919},{"style":859},[2920],{"type":510,"value":2921},"(id)], revalidate: ",{"type":504,"tag":847,"props":2923,"children":2924},{"style":912},[2925],{"type":510,"value":1868},{"type":504,"tag":847,"props":2927,"children":2928},{"style":859},[2929],{"type":510,"value":1873},{"type":504,"tag":847,"props":2931,"children":2932},{"class":849,"line":1668},[2933,2938,2943,2947,2952,2957,2962,2966],{"type":504,"tag":847,"props":2934,"children":2935},{"style":859},[2936],{"type":510,"value":2937},"  }).",{"type":504,"tag":847,"props":2939,"children":2940},{"style":854},[2941],{"type":510,"value":2942},"then",{"type":504,"tag":847,"props":2944,"children":2945},{"style":859},[2946],{"type":510,"value":1586},{"type":504,"tag":847,"props":2948,"children":2949},{"style":1589},[2950],{"type":510,"value":2951},"r",{"type":504,"tag":847,"props":2953,"children":2954},{"style":879},[2955],{"type":510,"value":2956}," =>",{"type":504,"tag":847,"props":2958,"children":2959},{"style":859},[2960],{"type":510,"value":2961}," r.",{"type":504,"tag":847,"props":2963,"children":2964},{"style":854},[2965],{"type":510,"value":1899},{"type":504,"tag":847,"props":2967,"children":2968},{"style":859},[2969],{"type":510,"value":2970},"())\n",{"type":504,"tag":847,"props":2972,"children":2973},{"class":849,"line":1700},[2974],{"type":504,"tag":847,"props":2975,"children":2976},{"style":859},[2977],{"type":510,"value":1727},{"type":504,"tag":516,"props":2979,"children":2980},{},[2981],{"type":510,"value":2982},"收益：",{"type":504,"tag":530,"props":2984,"children":2985},{},[2986,2991],{"type":504,"tag":534,"props":2987,"children":2988},{},[2989],{"type":510,"value":2990},"策略可审计（容易 code review）",{"type":504,"tag":534,"props":2992,"children":2993},{},[2994],{"type":510,"value":2995},"失效可统一（tag 命名规范化）",{"type":504,"tag":750,"props":2997,"children":2999},{"id":2998},"_62-tag-驱动失效优先于path-驱动失效",[3000],{"type":510,"value":3001},"6.2 “tag 驱动失效”优先于“path 驱动失效”",{"type":504,"tag":530,"props":3003,"children":3004},{},[3005,3010],{"type":504,"tag":534,"props":3006,"children":3007},{},[3008],{"type":510,"value":3009},"数据域（posts\u002Fusers\u002Fproducts）→ tag",{"type":504,"tag":534,"props":3011,"children":3012},{},[3013],{"type":510,"value":3014},"页面输出（某个路径的组合渲染结果）→ path（作为补充）",{"type":504,"tag":750,"props":3016,"children":3018},{"id":3017},"_63-mutation-的统一收尾协议",[3019],{"type":510,"value":3020},"6.3 mutation 的统一收尾协议",{"type":504,"tag":530,"props":3022,"children":3023},{},[3024,3052],{"type":504,"tag":534,"props":3025,"children":3026},{},[3027,3029],{"type":510,"value":3028},"Server Action \u002F 写接口成功后：\n",{"type":504,"tag":530,"props":3030,"children":3031},{},[3032,3041],{"type":504,"tag":534,"props":3033,"children":3034},{},[3035],{"type":504,"tag":656,"props":3036,"children":3038},{"className":3037},[],[3039],{"type":510,"value":3040},"revalidateTag(受影响的数据域)",{"type":504,"tag":534,"props":3042,"children":3043},{},[3044,3046],{"type":510,"value":3045},"如需要：",{"type":504,"tag":656,"props":3047,"children":3049},{"className":3048},[],[3050],{"type":510,"value":3051},"revalidatePath(受影响的聚合页)",{"type":504,"tag":534,"props":3053,"children":3054},{},[3055,3057],{"type":510,"value":3056},"UI 层：\n",{"type":504,"tag":530,"props":3058,"children":3059},{},[3060,3070],{"type":504,"tag":534,"props":3061,"children":3062},{},[3063,3065],{"type":510,"value":3064},"留在当前路由：",{"type":504,"tag":656,"props":3066,"children":3068},{"className":3067},[],[3069],{"type":510,"value":1215},{"type":504,"tag":534,"props":3071,"children":3072},{},[3073,3075,3080],{"type":510,"value":3074},"跳转到新路由：",{"type":504,"tag":656,"props":3076,"children":3078},{"className":3077},[],[3079],{"type":510,"value":2255},{"type":510,"value":3081},"（必要时仍 refresh\u002F失效）",{"type":504,"tag":750,"props":3083,"children":3085},{"id":3084},"_64-对强一致用户态默认-no-store",[3086],{"type":510,"value":3087},"6.4 对“强一致用户态”默认 no-store",{"type":504,"tag":530,"props":3089,"children":3090},{},[3091],{"type":504,"tag":534,"props":3092,"children":3093},{},[3094,3096],{"type":510,"value":3095},"用户资料\u002F权限\u002F购物车\u002F通知数等：\n",{"type":504,"tag":530,"props":3097,"children":3098},{},[3099,3109],{"type":504,"tag":534,"props":3100,"children":3101},{},[3102,3104],{"type":510,"value":3103},"默认 ",{"type":504,"tag":656,"props":3105,"children":3107},{"className":3106},[],[3108],{"type":510,"value":2125},{"type":504,"tag":534,"props":3110,"children":3111},{},[3112],{"type":510,"value":3113},"并显式让相关 segment dynamic（避免被静态化策略误伤）",{"type":504,"tag":577,"props":3115,"children":3117},{"id":3116},"_7-与-suspense-路由边界的协作体验层",[3118],{"type":510,"value":3119},"7. 与 Suspense \u002F 路由边界的协作（体验层）",{"type":504,"tag":516,"props":3121,"children":3122},{},[3123],{"type":510,"value":3124},"缓存\u002F刷新做对了还不够：你还需要避免 refresh 带来的“整页闪烁”。",{"type":504,"tag":530,"props":3126,"children":3127},{},[3128,3141],{"type":504,"tag":534,"props":3129,"children":3130},{},[3131,3133,3139],{"type":510,"value":3132},"用合理的 ",{"type":504,"tag":656,"props":3134,"children":3136},{"className":3135},[],[3137],{"type":510,"value":3138},"layout.tsx",{"type":510,"value":3140}," 保持稳定壳",{"type":504,"tag":534,"props":3142,"children":3143},{},[3144,3145,3151,3152,3158],{"type":510,"value":2187},{"type":504,"tag":656,"props":3146,"children":3148},{"className":3147},[],[3149],{"type":510,"value":3150},"loading.tsx",{"type":510,"value":696},{"type":504,"tag":656,"props":3153,"children":3155},{"className":3154},[],[3156],{"type":510,"value":3157},"\u003CSuspense>",{"type":510,"value":3159}," 把等待限制在局部边界",{"type":504,"tag":516,"props":3161,"children":3162},{},[3163,3165,3170],{"type":510,"value":3164},"（这能把 ",{"type":504,"tag":656,"props":3166,"children":3168},{"className":3167},[],[3169],{"type":510,"value":1215},{"type":510,"value":3171}," 的体感从“整页重载”变成“局部更新”。）",{"type":504,"tag":577,"props":3173,"children":3175},{"id":3174},"关联阅读",[3176],{"type":510,"value":3174},{"type":504,"tag":530,"props":3178,"children":3179},{},[3180,3201,3221,3241,3261,3281],{"type":504,"tag":534,"props":3181,"children":3182},{},[3183,3185],{"type":510,"value":3184},"App Router 的 segment tree \u002F layout \u002F loading 与 prefetch：\n",{"type":504,"tag":530,"props":3186,"children":3187},{},[3188],{"type":504,"tag":534,"props":3189,"children":3190},{},[3191],{"type":504,"tag":3192,"props":3193,"children":3195},"a",{"href":3194},"..\u002F10-routing-and-navigation\u002F03-next-app-router-segments-layout-loading-error-not-found-prefetch.md",[3196],{"type":504,"tag":656,"props":3197,"children":3199},{"className":3198},[],[3200],{"type":510,"value":3194},{"type":504,"tag":534,"props":3202,"children":3203},{},[3204,3206],{"type":510,"value":3205},"路由与 URL state 心智模型：\n",{"type":504,"tag":530,"props":3207,"children":3208},{},[3209],{"type":504,"tag":534,"props":3210,"children":3211},{},[3212],{"type":504,"tag":3192,"props":3213,"children":3215},{"href":3214},"..\u002F10-routing-and-navigation\u002F01-routing-and-url-state-mental-model.md",[3216],{"type":504,"tag":656,"props":3217,"children":3219},{"className":3218},[],[3220],{"type":510,"value":3214},{"type":504,"tag":534,"props":3222,"children":3223},{},[3224,3226],{"type":510,"value":3225},"数据层缓存与失效（客户端视角）：\n",{"type":504,"tag":530,"props":3227,"children":3228},{},[3229],{"type":504,"tag":534,"props":3230,"children":3231},{},[3232],{"type":504,"tag":3192,"props":3233,"children":3235},{"href":3234},"..\u002F11-data-layer\u002F02-tanstack-query-caching-and-invalidation.md",[3236],{"type":504,"tag":656,"props":3237,"children":3239},{"className":3238},[],[3240],{"type":510,"value":3234},{"type":504,"tag":534,"props":3242,"children":3243},{},[3244,3246],{"type":510,"value":3245},"一致性与乐观更新：\n",{"type":504,"tag":530,"props":3247,"children":3248},{},[3249],{"type":504,"tag":534,"props":3250,"children":3251},{},[3252],{"type":504,"tag":3192,"props":3253,"children":3255},{"href":3254},"..\u002F11-data-layer\u002F03-optimistic-updates-and-consistency.md",[3256],{"type":504,"tag":656,"props":3257,"children":3259},{"className":3258},[],[3260],{"type":510,"value":3254},{"type":504,"tag":534,"props":3262,"children":3263},{},[3264,3266],{"type":510,"value":3265},"Suspense 与加载态边界：\n",{"type":504,"tag":530,"props":3267,"children":3268},{},[3269],{"type":504,"tag":534,"props":3270,"children":3271},{},[3272],{"type":504,"tag":3192,"props":3273,"children":3275},{"href":3274},"..\u002F09-react-18-in-practice\u002F04-suspense-loading-boundary-design.md",[3276],{"type":504,"tag":656,"props":3277,"children":3279},{"className":3278},[],[3280],{"type":510,"value":3274},{"type":504,"tag":534,"props":3282,"children":3283},{},[3284,3286],{"type":510,"value":3285},"渲染与交付总览：\n",{"type":504,"tag":530,"props":3287,"children":3288},{},[3289],{"type":504,"tag":534,"props":3290,"children":3291},{},[3292],{"type":504,"tag":3192,"props":3293,"children":3295},{"href":3294},".\u002FREADME.md",[3296],{"type":504,"tag":656,"props":3297,"children":3299},{"className":3298},[],[3300],{"type":510,"value":3294},{"type":504,"tag":3302,"props":3303,"children":3304},"style",{},[3305],{"type":510,"value":3306},"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":841,"searchDepth":632,"depth":632,"links":3308},[3309,3310,3316,3321,3322,3333,3340,3346,3347],{"id":579,"depth":632,"text":582},{"id":712,"depth":632,"text":715,"children":3311},[3312,3313,3314,3315],{"id":752,"depth":666,"text":755},{"id":794,"depth":666,"text":797},{"id":981,"depth":666,"text":984},{"id":1183,"depth":666,"text":1186},{"id":1249,"depth":632,"text":1252,"children":3317},[3318,3319,3320],{"id":1255,"depth":666,"text":1258},{"id":1315,"depth":666,"text":1318},{"id":1366,"depth":666,"text":1369},{"id":1420,"depth":632,"text":1423},{"id":2027,"depth":632,"text":2030,"children":3323},[3324,3325,3327,3329,3330,3332],{"id":2033,"depth":666,"text":2036},{"id":2076,"depth":666,"text":3326},"4.2 以为 fetch 默认实时，实际被 Data Cache 复用",{"id":2141,"depth":666,"text":3328},"4.3 用了 revalidatePath，但数据被多个路由复用",{"id":2198,"depth":666,"text":2201},{"id":2265,"depth":666,"text":3331},"4.5 unstable_cache\u002F自定义缓存：失效体系缺失",{"id":2327,"depth":666,"text":2330},{"id":2379,"depth":632,"text":2382,"children":3334},[3335,3336,3337,3338,3339],{"id":2385,"depth":666,"text":2388},{"id":2432,"depth":666,"text":2435},{"id":2460,"depth":666,"text":2463},{"id":2542,"depth":666,"text":2545},{"id":2598,"depth":666,"text":2601},{"id":2634,"depth":632,"text":2637,"children":3341},[3342,3343,3344,3345],{"id":2640,"depth":666,"text":2643},{"id":2998,"depth":666,"text":3001},{"id":3017,"depth":666,"text":3020},{"id":3084,"depth":666,"text":3087},{"id":3116,"depth":632,"text":3119},{"id":3174,"depth":632,"text":3174},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":3349},"\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":3351},"\u003Cpath fill=\"currentColor\" d=\"M3 4h18v2H3zm0 7h12v2H3zm0 7h18v2H3z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":3353},"\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":3355,"height":3355,"rotate":4,"vFlip":6,"hFlip":6,"body":3356},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>"]