@@ -50,13 +50,17 @@ export function useCachedResponsivePrecommitValue<T>(
50
50
const [ , rerender ] = useState < { } | null > ( null ) ;
51
51
const lastCommittedParentCache = useRef < ParentCache < T > | null > ( null ) ;
52
52
53
+ const maybeHiddenOrFastRefresh = useRef ( false ) ;
53
54
useEffect ( ( ) => {
54
55
return ( ) => {
55
56
// Attempt to detect if the component was
56
57
// hidden (by Offscreen API), or fast refresh occured;
57
58
// 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 ;
60
64
} ;
61
65
} , [ ] ) ;
62
66
@@ -78,28 +82,32 @@ export function useCachedResponsivePrecommitValue<T>(
78
82
//
79
83
// After the above, we have a non-disposed item and a cleanup function, which we
80
84
// 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 ;
96
92
}
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 ( { } ) ;
102
93
}
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 ( { } ) ;
103
111
} , [ parentCache ] ) ;
104
112
105
113
if ( lastCommittedParentCache . current === parentCache ) {
0 commit comments