@@ -50,13 +50,17 @@ export function useCachedResponsivePrecommitValue<T>(
5050 const [ , rerender ] = useState < { } | null > ( null ) ;
5151 const lastCommittedParentCache = useRef < ParentCache < T > | null > ( null ) ;
5252
53+ const maybeHiddenOrFastRefresh = useRef ( false ) ;
5354 useEffect ( ( ) => {
5455 return ( ) => {
5556 // Attempt to detect if the component was
5657 // hidden (by Offscreen API), or fast refresh occured;
5758 // Only in these situations would the effect cleanup
58- // for "unmounting" run multiple times.
59- lastCommittedParentCache . current = null ;
59+ // for "unmounting" run multiple times, so if
60+ // we are ever able to read this ref with a value
61+ // of true, it means that one of these cases
62+ // has happened.
63+ maybeHiddenOrFastRefresh . current = true ;
6064 } ;
6165 } , [ ] ) ;
6266
@@ -78,28 +82,32 @@ export function useCachedResponsivePrecommitValue<T>(
7882 //
7983 // After the above, we have a non-disposed item and a cleanup function, which we
8084 // can pass to onCommit.
81- const undisposedPair = cacheItem . permanentRetainIfNotDisposed (
82- disposeOfTemporaryRetain ,
83- ) ;
84- if ( undisposedPair !== null ) {
85- onCommit ( undisposedPair ) ;
86- } else {
87- // The cache item we created during render has been disposed. Check if the parent
88- // cache is populated.
89- const existingCacheItemCleanupPair =
90- parentCache . getAndPermanentRetainIfPresent ( ) ;
91- if ( existingCacheItemCleanupPair !== null ) {
92- onCommit ( existingCacheItemCleanupPair ) ;
93- } else {
94- // We did not find an item in the parent cache, create a new one.
95- onCommit ( parentCache . factory ( ) ) ;
85+ if ( maybeHiddenOrFastRefresh . current === false ) {
86+ const undisposedPair = cacheItem . permanentRetainIfNotDisposed (
87+ disposeOfTemporaryRetain ,
88+ ) ;
89+ if ( undisposedPair !== null ) {
90+ onCommit ( undisposedPair ) ;
91+ return ;
9692 }
97- // TODO: Consider whether we always want to rerender if the committed item
98- // was not returned during the last render, or whether some callers will
99- // prefer opting out of this behavior (e.g. if every disposable item behaves
100- // identically, but must be loaded.)
101- rerender ( { } ) ;
10293 }
94+ maybeHiddenOrFastRefresh . current = false ;
95+
96+ // The cache item we created during render has been disposed. Check if the parent
97+ // cache is populated.
98+ const existingCacheItemCleanupPair =
99+ parentCache . getAndPermanentRetainIfPresent ( ) ;
100+ if ( existingCacheItemCleanupPair !== null ) {
101+ onCommit ( existingCacheItemCleanupPair ) ;
102+ } else {
103+ // We did not find an item in the parent cache, create a new one.
104+ onCommit ( parentCache . factory ( ) ) ;
105+ }
106+ // TODO: Consider whether we always want to rerender if the committed item
107+ // was not returned during the last render, or whether some callers will
108+ // prefer opting out of this behavior (e.g. if every disposable item behaves
109+ // identically, but must be loaded.)
110+ rerender ( { } ) ;
103111 } , [ parentCache ] ) ;
104112
105113 if ( lastCommittedParentCache . current === parentCache ) {
0 commit comments