Skip to content

Commit 5af24f3

Browse files
committed
Fix bug that causes the useLoader to not rerender
1 parent d712003 commit 5af24f3

File tree

1 file changed

+39
-54
lines changed

1 file changed

+39
-54
lines changed

src/hooks/useLoader.ts

Lines changed: 39 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,63 @@ export type CacheOptions<R> = EntryOptions<R> & {
77
initial?: R,
88
};
99

10-
export function useLoader<R>({initial, ...options}: CacheOptions<R>): R {
11-
const {cacheKey} = options;
12-
const loadedValue: R|undefined = cache.get<R>(cacheKey)?.result;
13-
const [value, setValue] = useState(loadedValue !== undefined ? loadedValue : initial);
10+
export function useLoader<R>({initial, ...currentOptions}: CacheOptions<R>): R {
11+
const optionsRef = useRef(currentOptions);
12+
const [value, setValue] = useState(() => cache.get<R>(currentOptions.cacheKey)?.result ?? initial);
1413
const mountedRef = useRef(true);
15-
const initialRef = useRef(initial);
16-
const previousCacheKey = useRef(cacheKey);
1714

18-
const load = useStableCallback(() => {
19-
try {
20-
setValue(cache.load(options));
21-
} catch (result: unknown) {
22-
if (result instanceof Promise) {
23-
result.then((resolvedValue: R) => {
24-
if (mountedRef.current) {
25-
setValue(resolvedValue);
26-
}
27-
});
28-
29-
return;
30-
}
31-
32-
setValue(undefined);
33-
}
34-
});
35-
36-
const reset = useStableCallback(() => {
37-
const newLoadedValue: R|undefined = cache.get<R>(cacheKey)?.result;
38-
39-
setValue(newLoadedValue !== undefined ? newLoadedValue : initial);
40-
41-
load();
42-
});
43-
44-
useEffect(
45-
() => {
46-
if (previousCacheKey.current !== cacheKey) {
47-
reset();
48-
previousCacheKey.current = cacheKey;
15+
const load = useCallback(
16+
(options: EntryOptions<R>) => {
17+
try {
18+
setValue(cache.load(options));
19+
} catch (result: unknown) {
20+
if (result instanceof Promise) {
21+
result.then((resolvedValue: R) => {
22+
if (mountedRef.current) {
23+
setValue(resolvedValue);
24+
}
25+
});
26+
27+
return;
28+
}
29+
30+
setValue(undefined);
4931
}
5032
},
51-
[reset, cacheKey],
33+
[],
5234
);
5335

5436
useEffect(
5537
() => {
56-
if (initialRef.current !== undefined) {
57-
load();
38+
if (initial !== undefined) {
39+
load(currentOptions);
5840
}
5941

6042
return () => {
6143
mountedRef.current = false;
6244
};
6345
},
64-
[load],
46+
// eslint-disable-next-line react-hooks/exhaustive-deps -- Should run only once
47+
[],
48+
);
49+
50+
useEffect(
51+
() => {
52+
if (optionsRef.current.cacheKey !== currentOptions.cacheKey) {
53+
setValue(initial);
54+
optionsRef.current = currentOptions;
55+
56+
if (initial !== undefined) {
57+
load(currentOptions);
58+
}
59+
}
60+
},
61+
[currentOptions, initial, load],
6562
);
6663

6764
if (value === undefined) {
68-
return cache.load(options);
65+
return cache.load(currentOptions);
6966
}
7067

7168
return value;
7269
}
73-
74-
type Callback = () => void;
75-
76-
function useStableCallback(callback: Callback): Callback {
77-
const ref = useRef<Callback>(undefined);
78-
79-
useEffect(() => {
80-
ref.current = callback;
81-
});
82-
83-
return useCallback(() => { ref.current?.(); }, []);
84-
}

0 commit comments

Comments
 (0)