T
TanStack2w ago
correct-apricot

Different pending routing behavior between <Navigate /> and navigate({...})

I have an nested <Outlet /> in my application which controls a stepper flow, the content below is what is rendered by the deeper <Outlet />. Only the <Navigate /> component renders the inner <Outlet /> as null for a moment causing a weird visual appearance.
export function RouteComponent() {
const query = useQuery({...});

if (query.data?.specialStatus === "done") {
return <Navigate to="/path/to/my/thing" />
}

return <div>...</div>;
}
export function RouteComponent() {
const query = useQuery({...});

if (query.data?.specialStatus === "done") {
return <Navigate to="/path/to/my/thing" />
}

return <div>...</div>;
}
When navigate({...}) is called, the isPending: true flag is set, and we navigate to the specified route with the pending component shown until data loads.
export function RouteComponent() {
const query = useQuery({...});
const navigate = useNavigate();

if (query.data?.specialStatus === "done") {
navigate({ to: "/path/to/my/thing" });
}

return <div>...</div>;
}
export function RouteComponent() {
const query = useQuery({...});
const navigate = useNavigate();

if (query.data?.specialStatus === "done") {
navigate({ to: "/path/to/my/thing" });
}

return <div>...</div>;
}
I'm not sure what I'm doing wrong that causes a temporary "null" outlet before navigation completes, it looks like <Navigate /> component calls navigate({...}) within a useEffect hook versus calling it directly in the component. This also works with the transition state working as expected (no null <Outlet /> rendered).
export function RouteComponent() {
const query = useQuery({...});
const navigate = useNavigate();

useEffect(() => {
if (query.data?.specialStatus === "done") {
navigate({ to: "/path/to/my/thing" });
}
}, [navigate, query.data?.specialStatus]);

return <div>...</div>;
}
export function RouteComponent() {
const query = useQuery({...});
const navigate = useNavigate();

useEffect(() => {
if (query.data?.specialStatus === "done") {
navigate({ to: "/path/to/my/thing" });
}
}, [navigate, query.data?.specialStatus]);

return <div>...</div>;
}
No description
3 Replies
like-gold
like-gold2w ago
a full reproducer would be helpful
correct-apricot
correct-apricotOP2w ago
Sounds good, when I find some time, I'll create a reproduction.
correct-apricot
correct-apricotOP2w ago
@Manuel Schiller https://stackblitz.com/edit/github-cty35c3q?file=src%2Froutes%2Fgizmos%2Fsecond.tsx Here you go, the long sleep in the beforeLoad function really highlights the "null" state.
Hannes Widrig
StackBlitz
@tanstack/router - null outlet navigation bug - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz

Did you find this page helpful?