Skip to content

Commit 15074a5

Browse files
fix useBlocker: avoid stale-capturing of blockerKey by making it non-reative value
1 parent 96d6c56 commit 15074a5

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

packages/react-router/lib/hooks.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,6 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
12571257
let { router, basename } = useDataRouterContext(DataRouterHook.UseBlocker);
12581258
let state = useDataRouterState(DataRouterStateHook.UseBlocker);
12591259

1260-
let [blockerKey, setBlockerKey] = React.useState("");
12611260
let blockerFunction = React.useCallback<BlockerFunction>(
12621261
(arg) => {
12631262
if (typeof shouldBlock !== "function") {
@@ -1290,11 +1289,13 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
12901289
[basename, shouldBlock]
12911290
);
12921291

1292+
let blockerKeyRef = React.useRef<string>("");
1293+
12931294
// This effect is in charge of blocker key assignment and deletion (which is
12941295
// tightly coupled to the key)
12951296
React.useEffect(() => {
12961297
let key = String(++blockerId);
1297-
setBlockerKey(key);
1298+
blockerKeyRef.current = key;
12981299
return () => router.deleteBlocker(key);
12991300
}, [router]);
13001301

@@ -1303,11 +1304,12 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
13031304
// effect so we don't get an orphaned blockerFunction in the router with a
13041305
// key of "". Until then we just have the IDLE_BLOCKER.
13051306
React.useEffect(() => {
1306-
if (blockerKey !== "") {
1307-
router.getBlocker(blockerKey, blockerFunction);
1307+
if (blockerKeyRef.current !== "") {
1308+
router.getBlocker(blockerKeyRef.current, blockerFunction);
13081309
}
1309-
}, [router, blockerKey, blockerFunction]);
1310+
}, [router, blockerFunction]);
13101311

1312+
let blockerKey = blockerKeyRef.current;
13111313
// Prefer the blocker from `state` not `router.state` since DataRouterContext
13121314
// is memoized so this ensures we update on blocker state updates
13131315
return blockerKey && state.blockers.has(blockerKey)

0 commit comments

Comments
 (0)