T
TanStack7d ago
extended-salmon

Using <Navigate /> causes "Maximum update depth exceeded"

Hey! I came across a weird bug that I'm not sure how to fix. Basically, I have some logic like auth etc. that redirects logged out users back to the login page. I noticed that if I'm using the <Navigate /> component to redirect them, it causes a "Maximum update depth exceeded", or more specifically, this error:
Uncaught (in promise) Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
at getRootForUpdatedFiber (react-dom_client.js?v=83969dac:3526:128)
at enqueueConcurrentHookUpdate (react-dom_client.js?v=83969dac:3510:16)
at dispatchSetStateInternal (react-dom_client.js?v=83969dac:6832:20)
at dispatchSetState (react-dom_client.js?v=83969dac:6803:9)
at Transitioner.router.startTransition (Transitioner.js?v=83969dac:23:5)
at router.js?v=83969dac:596:14
at new Promise (<anonymous>)
at RouterCore.load (router.js?v=83969dac:595:21)
at RouterCore.commitLocation (router.js?v=83969dac:451:14)
at RouterCore.buildAndCommitLocation (router.js?v=83969dac:514:19)
Uncaught (in promise) Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
at getRootForUpdatedFiber (react-dom_client.js?v=83969dac:3526:128)
at enqueueConcurrentHookUpdate (react-dom_client.js?v=83969dac:3510:16)
at dispatchSetStateInternal (react-dom_client.js?v=83969dac:6832:20)
at dispatchSetState (react-dom_client.js?v=83969dac:6803:9)
at Transitioner.router.startTransition (Transitioner.js?v=83969dac:23:5)
at router.js?v=83969dac:596:14
at new Promise (<anonymous>)
at RouterCore.load (router.js?v=83969dac:595:21)
at RouterCore.commitLocation (router.js?v=83969dac:451:14)
at RouterCore.buildAndCommitLocation (router.js?v=83969dac:514:19)
but if I use useEffect and navigate = useNavigate(), then I don't get this error. I can't figure out the exact reason it's happening though... Code examples below... My versions are the following:
"@tanstack/react-query": "^5.66.5",
"@tanstack/react-router": "^1.132.0",
"@tanstack/react-router-ssr-query": "^1.131.7",
"@tanstack/react-start": "^1.132.0",
"@tanstack/router-plugin": "^1.132.0",
"@tanstack/react-query": "^5.66.5",
"@tanstack/react-router": "^1.132.0",
"@tanstack/react-router-ssr-query": "^1.131.7",
"@tanstack/react-start": "^1.132.0",
"@tanstack/router-plugin": "^1.132.0",
Thanks!
3 Replies
extended-salmon
extended-salmonOP7d ago
This code works perfectly
import { Outlet, createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect } from "react";

import { useActiveAgent } from "@/providers/active-agent-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent
});

function RouteComponent() {
const navigate = useNavigate();

const { activeAgent } = useActiveAgent();

useEffect(() => {
if (activeAgent === undefined) {
return;
}

if (activeAgent === null) {
navigate({ to: "/{-$locale}/...", replace: true }); // This works with no issues
return;
}
}, [activeAgent]);

if (!activeAgent) {
return null;
}

return (
...
);
}
import { Outlet, createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect } from "react";

import { useActiveAgent } from "@/providers/active-agent-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent
});

function RouteComponent() {
const navigate = useNavigate();

const { activeAgent } = useActiveAgent();

useEffect(() => {
if (activeAgent === undefined) {
return;
}

if (activeAgent === null) {
navigate({ to: "/{-$locale}/...", replace: true }); // This works with no issues
return;
}
}, [activeAgent]);

if (!activeAgent) {
return null;
}

return (
...
);
}
but this code causes my web app to literally freeze.
import { Navigate, Outlet, createFileRoute } from "@tanstack/react-router";

import { useActiveAgent } from "@/providers/active-agent-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent
});

function RouteComponent() {
const { activeAgent } = useActiveAgent();

if (activeAgent === undefined) {
return null;
}

if (activeAgent === null) {
return <Navigate to={"/{-$locale}/..."} replace />; // This causes my app to freeze
}

return (
...
);
}
import { Navigate, Outlet, createFileRoute } from "@tanstack/react-router";

import { useActiveAgent } from "@/providers/active-agent-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent
});

function RouteComponent() {
const { activeAgent } = useActiveAgent();

if (activeAgent === undefined) {
return null;
}

if (activeAgent === null) {
return <Navigate to={"/{-$locale}/..."} replace />; // This causes my app to freeze
}

return (
...
);
}
Another example is this, which works perfectly
import { Outlet, createFileRoute, useNavigate, useRouterState } from "@tanstack/react-router";
import { useEffect } from "react";

import { useAuth } from "@/providers/auth-provider";
import { ThemeProvider } from "@/providers/theme-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent,
ssr: false
});

function RouteComponent() {
const navigate = useNavigate();

const { user, isResolving } = useAuth();
const router = useRouterState();

useEffect(() => {
if (isResolving) {
return;
}

if (!user) {
navigate({ to: "/{-$locale}/auth/sign-in", replace: true }); // This works
return;
}

if (!user.emailVerified) {
navigate({ to: "/{-$locale}/auth/verify-email", replace: true }); // Also this works
return;
}
}, [user, isResolving]);

if (isResolving || !user || !user.emailVerified) {
return null;
}

return (
<ThemeProvider defaultTheme="light">
...
</ThemeProvider>
);
}
import { Outlet, createFileRoute, useNavigate, useRouterState } from "@tanstack/react-router";
import { useEffect } from "react";

import { useAuth } from "@/providers/auth-provider";
import { ThemeProvider } from "@/providers/theme-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent,
ssr: false
});

function RouteComponent() {
const navigate = useNavigate();

const { user, isResolving } = useAuth();
const router = useRouterState();

useEffect(() => {
if (isResolving) {
return;
}

if (!user) {
navigate({ to: "/{-$locale}/auth/sign-in", replace: true }); // This works
return;
}

if (!user.emailVerified) {
navigate({ to: "/{-$locale}/auth/verify-email", replace: true }); // Also this works
return;
}
}, [user, isResolving]);

if (isResolving || !user || !user.emailVerified) {
return null;
}

return (
<ThemeProvider defaultTheme="light">
...
</ThemeProvider>
);
}
but then this code causes a lag spike and a max depth exceeded...
import { Navigate, Outlet, createFileRoute, useRouterState } from "@tanstack/react-router";

import { useAuth } from "@/providers/auth-provider";
import { ThemeProvider } from "@/providers/theme-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent,
ssr: false
});

function RouteComponent() {
const { user, isResolving } = useAuth();
const router = useRouterState();

if (isResolving) {
return null;
}

if (!user) {
return <Navigate to={"/{-$locale}/auth/sign-in"} replace />; // Causes a lag spike
}

if (!user.emailVerified) {
return <Navigate to={"/{-$locale}/auth/verify-email"} replace />; // Causes a lag spike
}

return (
<ThemeProvider defaultTheme="light">
...
</ThemeProvider>
);
}
import { Navigate, Outlet, createFileRoute, useRouterState } from "@tanstack/react-router";

import { useAuth } from "@/providers/auth-provider";
import { ThemeProvider } from "@/providers/theme-provider";

export const Route = createFileRoute("/{-$locale}/...")({
component: RouteComponent,
ssr: false
});

function RouteComponent() {
const { user, isResolving } = useAuth();
const router = useRouterState();

if (isResolving) {
return null;
}

if (!user) {
return <Navigate to={"/{-$locale}/auth/sign-in"} replace />; // Causes a lag spike
}

if (!user.emailVerified) {
return <Navigate to={"/{-$locale}/auth/verify-email"} replace />; // Causes a lag spike
}

return (
<ThemeProvider defaultTheme="light">
...
</ThemeProvider>
);
}
genetic-orange
genetic-orange7d ago
What version of React Router are you using?
extended-salmon
extended-salmonOP6d ago
I'm using 1.133.22
├── @tanstack/devtools-vite@0.3.9
├── @tanstack/eslint-config@0.3.2
├── @tanstack/react-devtools@0.7.7
├── @tanstack/react-query@5.90.5
├── @tanstack/react-query-devtools@5.90.2
├── @tanstack/react-router@1.133.22
├── @tanstack/react-router-devtools@1.133.22
├── @tanstack/react-router-ssr-query@1.133.22
├── @tanstack/react-start@1.133.22
├── @tanstack/router-plugin@1.133.22
├── @tanstack/devtools-vite@0.3.9
├── @tanstack/eslint-config@0.3.2
├── @tanstack/react-devtools@0.7.7
├── @tanstack/react-query@5.90.5
├── @tanstack/react-query-devtools@5.90.2
├── @tanstack/react-router@1.133.22
├── @tanstack/react-router-devtools@1.133.22
├── @tanstack/react-router-ssr-query@1.133.22
├── @tanstack/react-start@1.133.22
├── @tanstack/router-plugin@1.133.22

Did you find this page helpful?