Skip to content

Commit

Permalink
feat(react-router): add method to selectively removed cached matches
Browse files Browse the repository at this point in the history
  • Loading branch information
schiller-manuel committed Oct 18, 2024
1 parent 80ee58d commit 2fd17fd
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
10 changes: 9 additions & 1 deletion docs/framework/react/api/router/RouterType.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,17 @@ Invalidates route matches by forcing their `beforeLoad` and `load` functions to
- Type: `(opts?: {filter?: (d: MakeRouteMatch<TRouteTree>) => boolean}) => Promise<void>`
- This is useful any time your loader data might be out of date or stale. For example, if you have a route that displays a list of posts, and you have a loader function that fetches the list of posts from an API, you might want to invalidate the route matches for that route any time a new post is created so that the list of posts is always up-to-date.
- if `filter` is not supplied, all matches will be invalidated
- if `filter` is supplied, only matches for which `filter` returns `true` will be invalidate.
- if `filter` is supplied, only matches for which `filter` returns `true` will be invalidated.
- You might also want to invalidate the Router if you imperatively `reset` the router's `CatchBoundary` to trigger loaders again.
### `.removeCachedMatches` method
Remove cached route matches.
- Type: `(opts?: {filter?: (d: MakeRouteMatch<TRouteTree>) => boolean}) => void`
- if `filter` is not supplied, all cached matches will be removed
- if `filter` is supplied, only matches for which `filter` returns `true` will be removed.
### `.load` method
Loads all of the currently matched route matches and resolves when they are all loaded and ready to be rendered.
Expand Down
62 changes: 39 additions & 23 deletions packages/react-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ export class Router<
this.__store.batch(() => {
// this call breaks a route context of destination route after a redirect
// we should be fine not eagerly calling this since we call it later
// this.cleanCache()
// this.clearExpiredCache()

// Match the routes
pendingMatches = this.matchRoutes(next)
Expand Down Expand Up @@ -1867,7 +1867,7 @@ export class Router<
],
}
})
this.cleanCache()
this.clearExpiredCache()
})

//
Expand Down Expand Up @@ -2560,31 +2560,47 @@ export class Router<
return redirect
}

cleanCache = () => {
clearCache = (opts?: {
filter?: (d: MakeRouteMatch<TRouteTree>) => boolean
}) => {
const filter = opts?.filter
if (filter !== undefined) {
this.__store.setState((s) => {
return {
...s,
cachedMatches: s.cachedMatches.filter((m) => !filter(m)),
}
})
} else {
this.__store.setState((s) => {
return {
...s,
cachedMatches: [],
}
})
}
}

clearExpiredCache = () => {
// This is where all of the garbage collection magic happens
this.__store.setState((s) => {
return {
...s,
cachedMatches: s.cachedMatches.filter((d) => {
const route = this.looseRoutesById[d.routeId]!
const filter = (d: MakeRouteMatch<TRouteTree>) => {
const route = this.looseRoutesById[d.routeId]!

if (!route.options.loader) {
return false
}
if (!route.options.loader) {
return true
}

// If the route was preloaded, use the preloadGcTime
// otherwise, use the gcTime
const gcTime =
(d.preload
? (route.options.preloadGcTime ??
this.options.defaultPreloadGcTime)
: (route.options.gcTime ?? this.options.defaultGcTime)) ??
5 * 60 * 1000
// If the route was preloaded, use the preloadGcTime
// otherwise, use the gcTime
const gcTime =
(d.preload
? (route.options.preloadGcTime ?? this.options.defaultPreloadGcTime)
: (route.options.gcTime ?? this.options.defaultGcTime)) ??
5 * 60 * 1000

return d.status !== 'error' && Date.now() - d.updatedAt < gcTime
}),
}
})
return !(d.status !== 'error' && Date.now() - d.updatedAt < gcTime)
}
this.clearCache({ filter })
}

preloadRoute = async <
Expand Down

0 comments on commit 2fd17fd

Please sign in to comment.