fix(react-router): isolate client-only match hydration - #8185
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 836a97b
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version Preview1 package(s) bumped directly, 4 bumped as dependents. 🟩 Patch bumps
|
Bundle Size Benchmarks
The following scenarios have bundle-size changes compared with the baseline:
Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better. |
Merging this PR will degrade performance by 7.38%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | mem server error-paths not-found (vue) |
504.3 KB | 2,202.7 KB | -77.1% |
| ❌ | Memory | mem server error-paths not-found (solid) |
551 KB | 798.8 KB | -31.02% |
| ❌ | Memory | mem server error-paths unmatched (solid) |
561.7 KB | 628.5 KB | -10.63% |
| ❌ | Memory | mem server error-paths redirect (solid) |
350 KB | 383.4 KB | -8.71% |
| ❌ | Memory | mem client unique-location-churn (vue) |
429.3 KB | 460.7 KB | -6.82% |
| ❌ | Memory | mem server aborted-requests (solid) |
1.2 MB | 1.2 MB | -5.91% |
| ❌ | Memory | mem server server-fn-churn (react) |
372.6 KB | 393.5 KB | -5.32% |
| ❌ | Memory | mem server error-paths unmatched (vue) |
596.5 KB | 626.2 KB | -4.74% |
| ❌ | Memory | mem client loader-data-retention (solid) |
157.9 KB | 162.8 KB | -3.01% |
| ⚡ | Simulation | client-async-pipeline navigation loop (react) |
65 ms | 57.5 ms | +13.16% |
| ⚡ | Memory | mem server request-churn (react) |
701.4 KB | 639.6 KB | +9.65% |
| ⚡ | Memory | mem server peak-large-page (solid) |
1.2 MB | 1.1 MB | +8.55% |
| ⚡ | Memory | mem client preload-churn (react) |
813.6 KB | 753.3 KB | +8% |
| ⚡ | Memory | mem client interrupted-navigations (vue) |
380.2 KB | 353.9 KB | +7.41% |
| ⚡ | Memory | mem server peak-large-page (vue) |
1.1 MB | 1 MB | +7.31% |
| ⚡ | Memory | mem server aborted-requests (vue) |
1,087.3 KB | 1,014.3 KB | +7.2% |
| ⚡ | Simulation | ssr global-mw document (vue) |
630.7 ms | 590.4 ms | +6.82% |
| ⚡ | Memory | mem server server-fn-churn (vue) |
355.7 KB | 339.3 KB | +4.86% |
| ⚡ | Simulation | ssr global-mw document (solid) |
364.8 ms | 349.4 ms | +4.4% |
| ⚡ | Memory | mem client navigation-churn (solid) |
638 KB | 614.5 KB | +3.82% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing fix/issue-8180-hydration-boundary (836a97b) with main (0caf6b9)1
Stacked on #8183.
Summary
ClientOnlyhydration gate forssr: falseanddata-onlyroutesWhy
During React 18 hydration, the initial client load can synchronously publish transient match fetching state. A full-match subscription above a dehydrated client-only subtree invalidates that Suspense boundary before hydration completes, producing React error #421.
The match subscription now mounts only in the live
MatchInnerbranch. The pre-hydration fallback uses the same route-boundary construction without subscribing to match updates, whileTransitionerremains the sole loading authority.Closes #8180.
Verification
CI=1 NX_DAEMON=false pnpm nx run @tanstack/react-router:test:unit --outputStyle=stream --skipRemoteCacheCI=1 NX_DAEMON=false pnpm nx run @tanstack/react-router:test:types --outputStyle=stream --skipRemoteCacheCI=1 NX_DAEMON=false pnpm nx run @tanstack/react-router:test:eslint --outputStyle=stream --skipRemoteCachebeforeLoadreproduction: 3/3 passingloaderreproduction: 3/3 passing