Skip to content

Commit f6b5dae

Browse files
authored
Remove inaccurate console warning for POP navigations (#10030)
1 parent b620be2 commit f6b5dae

File tree

3 files changed

+24
-28
lines changed

3 files changed

+24
-28
lines changed

.changeset/healthy-moons-compete.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"react-router": patch
3+
"@remix-run/router": patch
4+
---
5+
6+
Remove inaccurate console warning for POP navigations

packages/react-router/lib/hooks.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -831,9 +831,7 @@ export function useAsyncError(): unknown {
831831
return value?._error;
832832
}
833833

834-
// useBlocker() is a singleton for now since we don't have any compelling use
835-
// cases for multi-blocker yet
836-
let blockerKey = "blocker-singleton";
834+
let blockerId = 0;
837835

838836
/**
839837
* Allow the application to block navigations within the SPA and present the
@@ -843,6 +841,7 @@ let blockerKey = "blocker-singleton";
843841
*/
844842
export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
845843
let { router } = useDataRouterContext(DataRouterHook.UseBlocker);
844+
let [blockerKey] = React.useState(() => String(++blockerId));
846845

847846
let blockerFunction = React.useCallback<BlockerFunction>(
848847
(args) => {
@@ -856,7 +855,10 @@ export function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker {
856855
let blocker = router.getBlocker(blockerKey, blockerFunction);
857856

858857
// Cleanup on unmount
859-
React.useEffect(() => () => router.deleteBlocker(blockerKey), [router]);
858+
React.useEffect(
859+
() => () => router.deleteBlocker(blockerKey),
860+
[router, blockerKey]
861+
);
860862

861863
return blocker;
862864
}

packages/router/router.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,6 @@ export function createRouter(init: RouterInit): Router {
756756
// cancel active deferreds for eliminated routes.
757757
let activeDeferreds = new Map<string, DeferredData>();
758758

759-
// We ony support a single active blocker at the moment since we don't have
760-
// any compelling use cases for multi-blocker yet
761-
let activeBlocker: string | null = null;
762-
763759
// Store blocker functions in a separate Map outside of router state since
764760
// we don't need to update UI state if they change
765761
let blockerFunctions = new Map<string, BlockerFunction>();
@@ -784,7 +780,7 @@ export function createRouter(init: RouterInit): Router {
784780
}
785781

786782
warning(
787-
activeBlocker != null && delta === null,
783+
blockerFunctions.size === 0 || delta != null,
788784
"You are trying to use a blocker on a POP navigation to a location " +
789785
"that was not created by @remix-run/router. This will fail silently in " +
790786
"production. This can happen if you are navigating outside the router " +
@@ -2129,12 +2125,6 @@ export function createRouter(init: RouterInit): Router {
21292125

21302126
if (blockerFunctions.get(key) !== fn) {
21312127
blockerFunctions.set(key, fn);
2132-
if (activeBlocker == null) {
2133-
// This is now the active blocker
2134-
activeBlocker = key;
2135-
} else if (key !== activeBlocker) {
2136-
warning(false, "A router only supports one blocker at a time");
2137-
}
21382128
}
21392129

21402130
return blocker;
@@ -2143,9 +2133,6 @@ export function createRouter(init: RouterInit): Router {
21432133
function deleteBlocker(key: string) {
21442134
state.blockers.delete(key);
21452135
blockerFunctions.delete(key);
2146-
if (activeBlocker === key) {
2147-
activeBlocker = null;
2148-
}
21492136
}
21502137

21512138
// Utility function to update blockers, ensuring valid state transitions
@@ -2176,18 +2163,19 @@ export function createRouter(init: RouterInit): Router {
21762163
nextLocation: Location;
21772164
historyAction: HistoryAction;
21782165
}): string | undefined {
2179-
if (activeBlocker == null) {
2166+
if (blockerFunctions.size === 0) {
21802167
return;
21812168
}
21822169

2183-
// We only allow a single blocker at the moment. This will need to be
2184-
// updated if we enhance to support multiple blockers in the future
2185-
let blockerFunction = blockerFunctions.get(activeBlocker);
2186-
invariant(
2187-
blockerFunction,
2188-
"Could not find a function for the active blocker"
2189-
);
2190-
let blocker = state.blockers.get(activeBlocker);
2170+
// We ony support a single active blocker at the moment since we don't have
2171+
// any compelling use cases for multi-blocker yet
2172+
if (blockerFunctions.size > 1) {
2173+
warning(false, "A router only supports one blocker at a time");
2174+
}
2175+
2176+
let entries = Array.from(blockerFunctions.entries());
2177+
let [blockerKey, blockerFunction] = entries[entries.length - 1];
2178+
let blocker = state.blockers.get(blockerKey);
21912179

21922180
if (blocker && blocker.state === "proceeding") {
21932181
// If the blocker is currently proceeding, we don't need to re-check
@@ -2198,7 +2186,7 @@ export function createRouter(init: RouterInit): Router {
21982186
// At this point, we know we're unblocked/blocked so we need to check the
21992187
// user-provided blocker function
22002188
if (blockerFunction({ currentLocation, nextLocation, historyAction })) {
2201-
return activeBlocker;
2189+
return blockerKey;
22022190
}
22032191
}
22042192

0 commit comments

Comments
 (0)