1
1
'use client'
2
- import React , { use , useContext , useEffect , useRef , useMemo } from 'react' ;
2
+ import React , { use , useContext , useEffect , useRef , useMemo , useOptimistic , startTransition } from 'react' ;
3
3
import { SceneViewProps } from './Props.js' ;
4
4
import useNavigationEvent from './useNavigationEvent.js' ;
5
5
import BundlerContext from './BundlerContext.js' ;
@@ -17,15 +17,16 @@ const SceneRSCView = ({active, name, refetch: serverRefetch, errorFallback, chil
17
17
const { state, oldState, data, stateNavigator : { stateContext, historyManager} } = navigationEvent ;
18
18
const { crumbs, nextCrumb : { crumblessUrl : url } , oldUrl, oldData, history, historyAction} = stateContext ;
19
19
const { deserialize} = useContext ( BundlerContext ) ;
20
- const { fetching : ancestorFetching } = useContext ( RSCContext ) ;
20
+ const rscContext = useContext ( RSCContext ) ;
21
21
const sceneViewKey = name || ( typeof active === 'string' ? active : active [ 0 ] ) ;
22
22
const getShow = ( stateKey : string ) => (
23
23
active != null && state && (
24
24
typeof active === 'string' ? stateKey === active : active . indexOf ( stateKey ) !== - 1
25
25
)
26
26
) ;
27
27
const show = getShow ( state . key ) ;
28
- const ignoreCache = ! ! navigationEvent [ 'ignoreCache' ] ;
28
+ const refetcherState = { ancestorFetching : rscContext . fetching , ignoreCache : ! ! navigationEvent [ 'ignoreCache' ] } ;
29
+ const [ { ancestorFetching, ignoreCache} , refetcher ] = useOptimistic < any , void > ( refetcherState , ( ) => ( { ancestorFetching : false , ignoreCache : true } ) ) ;
29
30
const cachedHistory = ! ignoreCache && history && ! ! historyCache [ url ] ?. [ sceneViewKey ] ;
30
31
if ( ! rscCache . get ( navigationEvent ) ) rscCache . set ( navigationEvent , { } ) ;
31
32
const cachedSceneViews = rscCache . get ( navigationEvent ) ;
@@ -59,8 +60,8 @@ const SceneRSCView = ({active, name, refetch: serverRefetch, errorFallback, chil
59
60
const sceneView = ( ( ) => {
60
61
if ( ! show ) return null ;
61
62
if ( cachedHistory ) return historyCache [ url ] [ sceneViewKey ] ;
63
+ if ( cachedSceneViews [ sceneViewKey ] ) return cachedSceneViews [ sceneViewKey ] ;
62
64
if ( firstScene || ancestorFetching ) return children ;
63
- if ( fetching ) return cachedSceneViews [ sceneViewKey ] ;
64
65
return renderedSceneView . current . sceneView ;
65
66
} ) ( ) ;
66
67
useEffect ( ( ) => {
@@ -94,8 +95,14 @@ const SceneRSCView = ({active, name, refetch: serverRefetch, errorFallback, chil
94
95
} ) ;
95
96
const rscContextVal = useMemo ( ( ) => ( {
96
97
fetching : ancestorFetching || fetching ,
97
- setRefetch : ( refetch : any ) => refetchRef . current = refetch !== undefined ? refetch : serverRefetch
98
- } ) , [ ancestorFetching || fetching ] ) ;
98
+ setRefetch : ( refetch : any ) => refetchRef . current = refetch !== undefined ? refetch : serverRefetch ,
99
+ refetcher : ( ) => {
100
+ startTransition ( ( ) => {
101
+ delete cachedSceneViews [ sceneViewKey ] ;
102
+ refetcher ( ) ;
103
+ } )
104
+ }
105
+ } ) , [ ancestorFetching || fetching , cachedSceneViews , refetcher ] ) ;
99
106
return (
100
107
< ErrorBoundary errorFallback = { errorFallback } >
101
108
< RSCContext . Provider value = { rscContextVal } >
0 commit comments