Skip to content

Commit

Permalink
Clean up startTransition in Link (#40505)
Browse files Browse the repository at this point in the history
- Use React.startTransition instead of useTransition
- Upgrade to latest React experimental
- Split router cache invalidate into separate function

Some minor cleanup while verifying behaviors.
  • Loading branch information
timneutkens committed Sep 13, 2022
1 parent e6ed8ef commit 629c7f5
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 41 deletions.
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -178,8 +178,8 @@
"react-17": "npm:react@17.0.2",
"react-dom": "18.2.0",
"react-dom-17": "npm:react-dom@17.0.2",
"react-dom-exp": "npm:react-dom@0.0.0-experimental-7028ce745-20220907",
"react-exp": "npm:react@0.0.0-experimental-7028ce745-20220907",
"react-dom-exp": "npm:react-dom@0.0.0-experimental-c739cef2f-20220912",
"react-exp": "npm:react@0.0.0-experimental-c739cef2f-20220912",
"react-ssr-prepass": "1.0.8",
"react-virtualized": "9.22.3",
"relay-compiler": "13.0.2",
Expand Down
44 changes: 31 additions & 13 deletions packages/next/client/components/reducer.ts
Expand Up @@ -9,6 +9,31 @@ import type {
import { matchSegment } from './match-segments'
import { fetchServerResponse } from './app-router.client'

/**
* Invalidate cache one level down from the router state.
*/
// TODO-APP: Verify if this needs to be recursive.
function invalidateCacheByRouterState(
newCache: CacheNode,
existingCache: CacheNode,
routerState: FlightRouterState
) {
// Remove segment that we got data for so that it is filled in during rendering of subTreeData.
for (const key in routerState[1]) {
const segmentForParallelRoute = routerState[1][key][0]
const cacheKey = Array.isArray(segmentForParallelRoute)
? segmentForParallelRoute[1]
: segmentForParallelRoute
const existingParallelRoutesCacheNode =
existingCache.parallelRoutes.get(key)
if (existingParallelRoutesCacheNode) {
let parallelRouteCacheNode = new Map(existingParallelRoutesCacheNode)
parallelRouteCacheNode.delete(cacheKey)
newCache.parallelRoutes.set(key, parallelRouteCacheNode)
}
}
}

/**
* Fill cache with subTreeData based on flightDataPath
*/
Expand Down Expand Up @@ -56,19 +81,12 @@ function fillCacheWithNewSubTreeData(
: new Map(),
}

// Remove segment that we got data for so that it is filled in during rendering of subTreeData.
for (const key in flightDataPath[2][1]) {
const segmentForParallelRoute = flightDataPath[2][1][key][0]
const cacheKey = Array.isArray(segmentForParallelRoute)
? segmentForParallelRoute[1]
: segmentForParallelRoute
const existingParallelRoutesCacheNode =
existingChildCacheNode?.parallelRoutes.get(key)
if (existingParallelRoutesCacheNode) {
let parallelRouteCacheNode = new Map(existingParallelRoutesCacheNode)
parallelRouteCacheNode.delete(cacheKey)
childCacheNode.parallelRoutes.set(key, parallelRouteCacheNode)
}
if (existingChildCacheNode) {
invalidateCacheByRouterState(
childCacheNode,
existingChildCacheNode,
flightDataPath[2]
)
}

childSegmentMap.set(segmentForCache, childCacheNode)
Expand Down
19 changes: 5 additions & 14 deletions packages/next/client/link.tsx
Expand Up @@ -16,9 +16,6 @@ import { useIntersection } from './use-intersection'
import { getDomainLocale } from './get-domain-locale'
import { addBasePath } from './add-base-path'

// @ts-ignore useTransition exist
const hasUseTransition = typeof React.useTransition !== 'undefined'

type Url = string | UrlObject
type RequiredKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? never : K
Expand Down Expand Up @@ -110,7 +107,7 @@ function linkClicked(
shallow?: boolean,
scroll?: boolean,
locale?: string | false,
startTransition?: (cb: any) => void,
isAppRouter?: boolean,
prefetchEnabled?: boolean
): void {
const { nodeName } = e.currentTarget
Expand Down Expand Up @@ -141,8 +138,9 @@ function linkClicked(
}
}

if (startTransition) {
startTransition(navigate)
if (isAppRouter) {
// @ts-expect-error startTransition exists.
React.startTransition(navigate)
} else {
navigate()
}
Expand Down Expand Up @@ -305,13 +303,6 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkPropsReal>(
}

const p = prefetchProp !== false
const [, /* isPending */ startTransition] = hasUseTransition
? // Rules of hooks is disabled here because the useTransition will always exist with React 18.
// There is no difference between renders in this case, only between using React 18 vs 17.
// @ts-ignore useTransition exists
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useTransition()
: []
let router = React.useContext(RouterContext)

// TODO-APP: type error. Remove `as any`
Expand Down Expand Up @@ -442,7 +433,7 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkPropsReal>(
shallow,
scroll,
locale,
appRouter ? startTransition : undefined,
Boolean(appRouter),
p
)
}
Expand Down
24 changes: 12 additions & 12 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 629c7f5

Please sign in to comment.