The documentation of TanStack React Query (https://tanstack.com/query/v4/docs/react/guides/query-cancellation) explains how the queryFn
property can receive an object with a signal
property, which can be used to cancel a query, like in this example.
const query = useQuery({
queryKey: ['todos'],
queryFn: async ({ signal }) => {
const todosResponse = await fetch('/todos', {
signal,
})
const todos = await todosResponse.json()
const todoDetails = todos.map(async ({ details }) => {
const response = await fetch(details, {
signal,
})
return response.json()
})
return Promise.all(todoDetails)
},
})
The problem is that, with TypeScript, this signal property is type as AbortSignal | undefined
. With the API that I am using, having to conditionally check if the signal
is set adds a lot of complexity to the code so it would be very helpful to know under which conditions this signal
object is not defined. Any ideas would be much appreciated.
react-query v4.29.11
The signal
will exist if the AbortController
class exists. Let's take a look at the source code:
The signal
property is added to the query function context by addSignalProperty()
function, see below:
const addSignalProperty = (object: unknown) => {
Object.defineProperty(object, 'signal', {
enumerable: true,
get: () => {
if (abortController) {
this.abortSignalConsumed = true
return abortController.signal
}
return undefined
},
})
}
addSignalProperty(queryFnContext)
The abortController
is got by getAbortController()
function
export function getAbortController(): AbortController | undefined {
if (typeof AbortController === 'function') {
return new AbortController()
}
return
}
That's why the TS type of signal
property is: AbortSignal | undefined
.
The official documentation also mentions it.
The
AbortController
API is available in most runtime environments, but if the runtime environment does not support it then the query function will receiveundefined
in its place. You may choose to polyfill theAbortController
API if you wish, there are several available.