Skip to content

Commit 3ff99bd

Browse files
authored
Re-implement hmr-refresh in terms of refresh (#87135)
Based on: - #87134 --- hmr-refresh-reducer is identical to refresh-reducer except for the fact that it doesn't evict the prefetch cache. So this refactors both implementations to call the same shared function.
1 parent 1271708 commit 3ff99bd

File tree

21 files changed

+1039
-704
lines changed

21 files changed

+1039
-704
lines changed

packages/next/src/client/components/app-router-instance.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,7 @@ function runRemainingActions(
7979
// after the navigation has already finished and the queue is empty
8080
if (actionQueue.needsRefresh) {
8181
actionQueue.needsRefresh = false
82-
actionQueue.dispatch(
83-
{
84-
type: ACTION_REFRESH,
85-
origin: window.location.origin,
86-
},
87-
setState
88-
)
82+
actionQueue.dispatch({ type: ACTION_REFRESH }, setState)
8983
}
9084
}
9185
}
@@ -383,7 +377,6 @@ export const publicAppRouterInstance: AppRouterInstance = {
383377
startTransition(() => {
384378
dispatchAppRouterAction({
385379
type: ACTION_REFRESH,
386-
origin: window.location.origin,
387380
})
388381
})
389382
},
@@ -396,7 +389,6 @@ export const publicAppRouterInstance: AppRouterInstance = {
396389
startTransition(() => {
397390
dispatchAppRouterAction({
398391
type: ACTION_HMR_REFRESH,
399-
origin: window.location.origin,
400392
})
401393
})
402394
}

packages/next/src/client/components/layout-router.tsx

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
} from '../../shared/lib/hooks-client-context.shared-runtime'
5151
import { getParamValueFromCacheKey } from '../route-params'
5252
import type { Params } from '../../server/request/params'
53+
import { isDeferredRsc } from './router-reducer/ppr-navigations'
5354

5455
/**
5556
* Add refetch marker to router state at the point of the current layout segment.
@@ -375,11 +376,27 @@ function InnerLayoutRouter({
375376
// special case `null` to represent that this segment's data is missing. If
376377
// it's a promise, we need to unwrap it so we can determine whether or not the
377378
// data is missing.
378-
const resolvedRsc: React.ReactNode =
379-
typeof rsc === 'object' && rsc !== null && typeof rsc.then === 'function'
380-
? use(rsc)
381-
: rsc
379+
let resolvedRsc: React.ReactNode
380+
if (isDeferredRsc(rsc)) {
381+
const unwrappedRsc = use(rsc)
382+
if (unwrappedRsc === null) {
383+
// If the promise was resolved to `null`, it means the data for this
384+
// segment was not returned by the server. Suspend indefinitely. When this
385+
// happens, the router is responsible for triggering a new state update to
386+
// un-suspend this segment.
387+
use(unresolvedThenable) as never
388+
}
389+
resolvedRsc = unwrappedRsc
390+
} else {
391+
// This is not a deferred RSC promise. Don't need to unwrap it.
392+
resolvedRsc = rsc
393+
}
382394

395+
// TODO: At this point, the only reason `resolvedRsc` would be null is if the
396+
// data for this segment was fetched by a reducer that hasn't been migrated
397+
// yet to the Segment Cache implementation. It shouldn't happen for regular
398+
// navigations. Once we convert the remaining reducers, we can delete the
399+
// lazy fetching block below.
383400
if (!resolvedRsc) {
384401
// The data for this segment is not available, and there's no pending
385402
// navigation that will be able to fulfill it. We need to fetch more from
@@ -418,6 +435,7 @@ function InnerLayoutRouter({
418435
previousTree: fullTree,
419436
serverResponse,
420437
navigatedAt,
438+
retry: null,
421439
})
422440
})
423441

@@ -610,6 +628,14 @@ export default function OuterLayoutRouter({
610628
// (This only applies to page segments; layout segments cannot access search
611629
// params on the server.)
612630
const activeTree = parentTree[1][parallelRouterKey]
631+
if (activeTree === undefined) {
632+
// Could not find a matching segment. The client tree is inconsistent with
633+
// the server tree. Suspend indefinitely; the router will have already
634+
// detected the inconsistency when handling the server response, and
635+
// triggered a refresh of the page to recover.
636+
use(unresolvedThenable) as never
637+
}
638+
613639
const activeSegment = activeTree[0]
614640
const activeStateKey = createRouterCacheKey(activeSegment, true) // no search params
615641

0 commit comments

Comments
 (0)