Skip to content

Commit 14884d6

Browse files
committed
Refactor how router errors are reported to avoid strict mode issues
1 parent 4a0ca63 commit 14884d6

File tree

2 files changed

+19
-32
lines changed

2 files changed

+19
-32
lines changed

packages/react-router/lib/components.tsx

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -542,31 +542,22 @@ export function RouterProvider({
542542
nextLocation: Location;
543543
}>();
544544
let fetcherData = React.useRef<Map<string, any>>(new Map());
545-
let logErrorsAndSetState = React.useCallback(
546-
(newState: RouterState) => {
547-
setStateImpl((prevState) => {
548-
// Send loader/action errors through handleError
549-
if (newState.errors && onError) {
550-
Object.entries(newState.errors).forEach(([routeId, error]) => {
551-
if (prevState.errors?.[routeId] !== error) {
552-
onError(error, {
553-
location: newState.location,
554-
params: newState.matches[0]?.params ?? {},
555-
});
556-
}
557-
});
558-
}
559-
return newState;
560-
});
561-
},
562-
[onError],
563-
);
564545

565546
let setState = React.useCallback<RouterSubscriber>(
566547
(
567548
newState: RouterState,
568-
{ deletedFetchers, flushSync, viewTransitionOpts },
549+
{ deletedFetchers, newErrors, flushSync, viewTransitionOpts },
569550
) => {
551+
// Send router errors through onError
552+
if (newErrors && onError) {
553+
Object.values(newErrors).forEach((error) =>
554+
onError(error, {
555+
location: newState.location,
556+
params: newState.matches[0]?.params ?? {},
557+
}),
558+
);
559+
}
560+
570561
newState.fetchers.forEach((fetcher, key) => {
571562
if (fetcher.data !== undefined) {
572563
fetcherData.current.set(key, fetcher.data);
@@ -600,9 +591,9 @@ export function RouterProvider({
600591
// just update and be done with it
601592
if (!viewTransitionOpts || !isViewTransitionAvailable) {
602593
if (reactDomFlushSyncImpl && flushSync) {
603-
reactDomFlushSyncImpl(() => logErrorsAndSetState(newState));
594+
reactDomFlushSyncImpl(() => setStateImpl(newState));
604595
} else {
605-
React.startTransition(() => logErrorsAndSetState(newState));
596+
React.startTransition(() => setStateImpl(newState));
606597
}
607598
return;
608599
}
@@ -626,7 +617,7 @@ export function RouterProvider({
626617

627618
// Update the DOM
628619
let t = router.window!.document.startViewTransition(() => {
629-
reactDomFlushSyncImpl(() => logErrorsAndSetState(newState));
620+
reactDomFlushSyncImpl(() => setStateImpl(newState));
630621
});
631622

632623
// Clean up after the animation completes
@@ -665,13 +656,7 @@ export function RouterProvider({
665656
});
666657
}
667658
},
668-
[
669-
router.window,
670-
reactDomFlushSyncImpl,
671-
transition,
672-
renderDfd,
673-
logErrorsAndSetState,
674-
],
659+
[router.window, reactDomFlushSyncImpl, transition, renderDfd, onError],
675660
);
676661

677662
// Need to use a layout effect here so we are subscribed early enough to
@@ -694,7 +679,7 @@ export function RouterProvider({
694679
let newState = pendingState;
695680
let renderPromise = renderDfd.promise;
696681
let transition = router.window.document.startViewTransition(async () => {
697-
React.startTransition(() => logErrorsAndSetState(newState));
682+
React.startTransition(() => setStateImpl(newState));
698683
await renderPromise;
699684
});
700685
transition.finished.finally(() => {
@@ -705,7 +690,7 @@ export function RouterProvider({
705690
});
706691
setTransition(transition);
707692
}
708-
}, [pendingState, renderDfd, router.window, logErrorsAndSetState]);
693+
}, [pendingState, renderDfd, router.window]);
709694

710695
// When the new location finally renders and is committed to the DOM, this
711696
// effect will run to resolve the transition

packages/react-router/lib/router/router.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ export interface RouterSubscriber {
489489
state: RouterState,
490490
opts: {
491491
deletedFetchers: string[];
492+
newErrors: RouteData | null;
492493
viewTransitionOpts?: ViewTransitionOpts;
493494
flushSync: boolean;
494495
},
@@ -1292,6 +1293,7 @@ export function createRouter(init: RouterInit): Router {
12921293
[...subscribers].forEach((subscriber) =>
12931294
subscriber(state, {
12941295
deletedFetchers: unmountedFetchers,
1296+
newErrors: newState.errors ?? null,
12951297
viewTransitionOpts: opts.viewTransitionOpts,
12961298
flushSync: opts.flushSync === true,
12971299
}),

0 commit comments

Comments
 (0)