Commit b9e4866
committed
Simplify scroll restoration with shared ScrollRef on CacheNode
The scroll system previously relied on accumulating segment paths during
navigation, then matching those paths in layout-router to decide which
segments should scroll. This was necessary when CacheNodes were created
lazily during render, since we couldn't mark scroll targets on the nodes
themselves. But now that we construct the entire CacheNode tree
immediately upon navigation, we can use a much simpler approach.
Each navigation creates a single shared mutable ref (ScrollRef) and
assigns it to every new leaf CacheNode. When any segment's scroll
handler fires, it sets the ref to false, preventing other segments from
scrolling. This replaces all the segment path accumulation and matching
logic with a straightforward per-node flag.
The motivation for this refactor was a bug where calling refresh() from
a server action would scroll the page to the top. The old path-based
system had a semantic gap between null (no segments to scroll) and an
empty array (scroll everything) — when a server action triggered a
refresh with no new segments, the null value fell through to a code path
that scrolled unconditionally. The new model avoids this entirely:
refresh creates no new CacheNodes, so no ScrollRef is assigned, and
nothing scrolls.
There is extensive existing test coverage for scroll restoration
behavior. This adds one additional test for the server action refresh
bug.1 parent 1126661 commit b9e4866
File tree
16 files changed
+380
-310
lines changed- packages/next/src
- client
- app-dir
- components
- router-reducer
- reducers
- segment-cache
- test/e2e/app-dir/router-autoscroll
- app/server-action-refresh
16 files changed
+380
-310
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
307 | 308 | | |
308 | 309 | | |
309 | 310 | | |
310 | | - | |
| 311 | + | |
311 | 312 | | |
312 | 313 | | |
313 | 314 | | |
| |||
Lines changed: 14 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
277 | 278 | | |
278 | 279 | | |
279 | 280 | | |
280 | | - | |
| 281 | + | |
281 | 282 | | |
282 | 283 | | |
283 | 284 | | |
| |||
307 | 308 | | |
308 | 309 | | |
309 | 310 | | |
310 | | - | |
| 311 | + | |
311 | 312 | | |
312 | 313 | | |
313 | 314 | | |
| |||
356 | 357 | | |
357 | 358 | | |
358 | 359 | | |
359 | | - | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
360 | 364 | | |
361 | 365 | | |
362 | 366 | | |
| |||
373 | 377 | | |
374 | 378 | | |
375 | 379 | | |
376 | | - | |
| 380 | + | |
377 | 381 | | |
378 | 382 | | |
379 | 383 | | |
| |||
442 | 446 | | |
443 | 447 | | |
444 | 448 | | |
445 | | - | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
446 | 452 | | |
447 | 453 | | |
448 | 454 | | |
| |||
458 | 464 | | |
459 | 465 | | |
460 | 466 | | |
461 | | - | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
462 | 470 | | |
463 | 471 | | |
464 | 472 | | |
| |||
0 commit comments