-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Description
Which project does this relate to?
Router
Describe the bug
First of all, I'm sorry if the title of the issue does not describe what is happening.
I have two routes:
- the __root route with a loader performing a call to
fetchto a slow API - an index route with a loader also performing a call to
fetchto a slow API
Both calls forward the abortController.signal to fetch to ensure the request is canceled if necessary.
The index route is displaying a text input, and whenever the user types something, navigate is used which triggers a route reload.
If too many reloads are run, the error message "signal is aborted without reason" is triggered from the root view.
Your Example Website or App
https://stackblitz.com/edit/tanstack-router-juizcyv2?file=src%2Froutes%2Findex.tsx
Steps to Reproduce the Bug or Issue
- write one character at a time in the text input: it works well
- write many characters simultaneously: an error is triggered
Expected behavior
The abort error should be caught.
Screenshots or Videos
Screen.Recording.2025-04-03.at.13.41.43.mov
Platform
Additional context
root.tsx:
import * as React from 'react';
import { Link, Outlet, createRootRoute } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
export const Route = createRootRoute({
component: RootComponent,
loader: async ({ abortController }) => {
try {
const data = await fetch('https://httpstat.us/200?sleep=1000', {
signal: abortController.signal,
});
} catch (e) {
console.log('in __root, aborted');
throw e;
}
},
});
function RootComponent() {
return (
<>
<div className="p-2 flex gap-2 text-lg">
<Link
to="/"
activeProps={{
className: 'font-bold',
}}
activeOptions={{ exact: true }}
>
Home
</Link>{' '}
<Link
to="/about"
activeProps={{
className: 'font-bold',
}}
>
About
</Link>
</div>
<hr />
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
);
}index.tsx:
import * as React from 'react';
import { createFileRoute } from '@tanstack/react-router';
type Search = {
filter: string;
};
export const Route = createFileRoute('/')({
component: HomeComponent,
validateSearch: (search: Record<string, unknown>): Search => {
return {
filter: (search.filter as string) || '',
};
},
loaderDeps: ({ search }) => {
return {
filter: search.filter,
};
},
loader: async ({ deps, abortController }) => {
console.log('loading', deps.filter);
try {
const data = await fetch('https://httpstat.us/200?sleep=1000', {
signal: abortController.signal,
});
} catch (e) {
console.log('in index, signal aborted for', deps.filter);
throw e;
}
console.log('loaded:', deps.filter);
return { status: 'loaded: ' + deps.filter };
},
});
function HomeComponent() {
const search = Route.useSearch();
const navigate = Route.useNavigate();
const data = Route.useLoaderData();
return (
<div className="p-2">
<h3>Welcome Home!</h3>
<h4>Status: {data.status}</h4>
<input
className="bg-gray-300 border border-black"
value={search.filter}
onChange={(e) => {
navigate({
to: '/',
search: {
filter: e.target.value,
},
});
}}
/>
</div>
);
}Metadata
Metadata
Assignees
Labels
No labels