Skip to content

Commit d3de5d4

Browse files
committed
use ref of type bool to detect hmr
1 parent 3f441e0 commit d3de5d4

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

libs/isograph-react-disposable-state/src/useCachedResponsivePrecommitValue.ts

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)