This error occurs when using the deprecated array syntax for React Query's useQuery hook instead of the required object syntax. React Query v4 and v5 require passing configuration as a single object parameter.
This error appears when you're using React Query (TanStack Query) with the old v3 array-based syntax instead of the modern object-based syntax that became required in v4 and beyond. In React Query v3, you could call useQuery with separate parameters: useQuery(['todos'], fetchTodos, options). Starting with v4, the API changed to accept a single object parameter containing all configuration: useQuery({ queryKey: ['todos'], queryFn: fetchTodos, ...options }). This change was made to improve API consistency, provide better TypeScript support, and make the hook more maintainable as React Query added more configuration options. If you're seeing this error, you're likely using the legacy syntax in a project that has upgraded to v4 or v5, or you're following outdated documentation or examples.
Convert your useQuery calls from the old array syntax to the new object syntax.
Old syntax (v3):
import { useQuery } from '@tanstack/react-query';
const { data, error, isLoading } = useQuery(
['todos'],
fetchTodos,
{
staleTime: 5000,
refetchOnWindowFocus: false
}
);New syntax (v4+):
import { useQuery } from '@tanstack/react-query';
const { data, error, isLoading } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
staleTime: 5000,
refetchOnWindowFocus: false
});The key changes:
- Wrap all parameters in a single object
- Make queryKey and queryFn explicit object properties
- Move all options into the same object
If your query key includes variables, the same pattern applies.
Old syntax:
const { data } = useQuery(
['todo', todoId],
() => fetchTodo(todoId),
{ enabled: !!todoId }
);New syntax:
const { data } = useQuery({
queryKey: ['todo', todoId],
queryFn: () => fetchTodo(todoId),
enabled: !!todoId
});The query key array structure remains the same, but it's now passed as a property.
If you're using useQueries to run multiple queries in parallel, it also requires the object syntax.
Old syntax (v3):
const results = useQueries([
{ queryKey: ['post', 1], queryFn: () => fetchPost(1) },
{ queryKey: ['post', 2], queryFn: () => fetchPost(2) }
]);New syntax (v4+):
const results = useQueries({
queries: [
{ queryKey: ['post', 1], queryFn: () => fetchPost(1) },
{ queryKey: ['post', 2], queryFn: () => fetchPost(2) }
]
});Wrap the array of queries in an object with a queries property.
While updating syntax, review other breaking changes from the migration guide:
For v4:
// Query client defaults have changed
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// v4 defaults to staleTime: 0 (was undefined in v3)
refetchOnWindowFocus: true,
retry: 3
}
}
});For v5:
- initialPageParam is now required for infinite queries
- Some renamed properties (consult migration guide)
Check the official migration documentation at:
- v4: https://tanstack.com/query/v4/docs/framework/react/guides/migrating-to-react-query-4
- v5: https://tanstack.com/query/v5/docs/framework/react/guides/migrating-to-v5
Ensure all React Query packages are on the same version to avoid conflicts.
Check your package.json:
npm list @tanstack/react-query
# or
yarn list @tanstack/react-queryUpdate all packages to the same version:
npm install @tanstack/react-query@latest
# Also update devtools if you use them
npm install @tanstack/react-query-devtools@latestClear node_modules and reinstall if you see version mismatches:
rm -rf node_modules package-lock.json
npm installWhy the API changed
React Query's maintainers switched to object syntax for several reasons:
1. Extensibility: As React Query added more features (like mutations, infinite queries, suspense support), the number of parameters grew unwieldy
2. TypeScript support: Object properties provide better type inference and autocomplete than positional parameters
3. Developer experience: Named properties make code more self-documenting and easier to refactor
4. Consistency: All TanStack libraries (Query, Table, Router) now use consistent object-based APIs
Gradual migration strategy
If you have a large codebase:
1. Enable ESLint rule @tanstack/query/prefer-query-object-syntax (available in v4)
2. Use codemod tools from the migration guide to automate conversion
3. Search for useQuery( and useQueries( to find all instances
4. Consider creating wrapper hooks that enforce object syntax organization-wide
Performance considerations
The syntax change has no performance impact. Query caching, deduplication, and automatic refetching work identically in both syntaxes. The only difference is the calling convention.
GraphQL Code Generator users
If using graphql-code-generator with the typescript-react-query plugin, update to the latest version which generates v4+ compatible code. Older plugin versions generate v3 syntax that will cause this error.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite