Skip to content

Commit 224564e

Browse files
committed
fix cleanup
1 parent ad2ed05 commit 224564e

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export function useDisposableState<T = never>(
2222
const preCommitItem = useCachedResponsivePrecommitValue(
2323
parentCache,
2424
(pair) => {
25-
itemCleanupPairRef.current?.[1]();
2625
itemCleanupPairRef.current = pair;
2726
},
2827
);
@@ -47,14 +46,23 @@ export function useDisposableState<T = never>(
4746
[stateFromDisposableStateHook],
4847
);
4948

50-
useEffect(function cleanupItemCleanupPairRefIfSetStateNotCalled() {
51-
return () => {
52-
if (itemCleanupPairRef.current !== null) {
53-
itemCleanupPairRef.current[1]();
54-
itemCleanupPairRef.current = null;
49+
const lastCommittedParentCache = useRef<ParentCache<T> | null>(null);
50+
51+
useEffect(
52+
function cleanupItemCleanupPairRefIfSetStateNotCalled() {
53+
if (lastCommittedParentCache.current === parentCache) {
54+
return;
5555
}
56-
};
57-
}, []);
56+
lastCommittedParentCache.current = parentCache;
57+
// capture last set pair in a variable
58+
const current = itemCleanupPairRef.current;
59+
return () => {
60+
// current is a stale variable
61+
current?.[1]();
62+
};
63+
},
64+
[parentCache],
65+
);
5866

5967
// Safety: we can be in one of three states. Pre-commit, in which case
6068
// preCommitItem is assigned, post-commit but before setState has been

libs/isograph-react-disposable-state/src/useLazyDisposableState.test.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ItemCleanupPair } from '@isograph/disposable-types';
2-
import React, { useEffect, useState } from 'react';
2+
import React, { StrictMode, useEffect, useState } from 'react';
33
import { create } from 'react-test-renderer';
44
import { describe, expect, test, vi } from 'vitest';
55
import { ParentCache } from './ParentCache';
@@ -55,7 +55,12 @@ describe('useLazyDisposableState', async () => {
5555
return null;
5656
}
5757

58-
const root = create(<TestComponent />, { unstable_isConcurrent: true });
58+
const root = create(
59+
<StrictMode>
60+
<TestComponent />
61+
</StrictMode>,
62+
{ unstable_isConcurrent: true },
63+
);
5964
await committed.promise;
6065
expect(cache1.disposeItem).toHaveBeenCalled();
6166
expect(cache1.cache.factory).toHaveBeenCalledOnce();

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,24 @@ export function useLazyDisposableState<T>(
2323
state: T;
2424
} {
2525
const itemCleanupPairRef = useRef<ItemCleanupPair<T> | null>(null);
26-
2726
const preCommitItem = useCachedResponsivePrecommitValue(
2827
parentCache,
2928
(pair) => {
30-
itemCleanupPairRef.current?.[1]();
3129
itemCleanupPairRef.current = pair;
3230
},
3331
);
3432

33+
const lastCommittedParentCache = useRef<ParentCache<T> | null>(null);
3534
useEffect(() => {
35+
if (lastCommittedParentCache.current === parentCache) {
36+
return;
37+
}
38+
lastCommittedParentCache.current = parentCache;
39+
// capture last set pair in a variable
40+
const current = itemCleanupPairRef.current;
3641
return () => {
37-
const cleanupFn = itemCleanupPairRef.current?.[1];
42+
// current is a stale variable
43+
const cleanupFn = current?.[1];
3844
// TODO confirm useEffect is called in order.
3945
if (cleanupFn == null) {
4046
throw new Error(
@@ -43,7 +49,7 @@ export function useLazyDisposableState<T>(
4349
}
4450
return cleanupFn();
4551
};
46-
}, []);
52+
}, [parentCache]);
4753

4854
const returnedItem = preCommitItem?.state ?? itemCleanupPairRef.current?.[0];
4955

libs/isograph-react-disposable-state/src/useUpdatableDisposableState.test.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, test, vi, expect } from 'vitest';
2-
import React from 'react';
2+
import React, { StrictMode } from 'react';
33
import { create } from 'react-test-renderer';
44
import {
55
useUpdatableDisposableState,
@@ -45,7 +45,8 @@ function promiseAndResolver() {
4545
// not is a bit worrisome.
4646
async function awaitableCreate(Component, isConcurrent) {
4747
const element = create(
48-
Component,
48+
<StrictMode>{Component}</StrictMode>,
49+
4950
isConcurrent ? { unstable_isConcurrent: true } : undefined,
5051
);
5152
await shortPromise();

0 commit comments

Comments
 (0)