eslint-plugin-react-query-must-invalidate-queries
ESLint plugin to enforce best practices when working with TanStack Query
Installation
npm install eslint-plugin-react-query-must-invalidate-queries --save-dev
# or
yarn add eslint-plugin-react-query-must-invalidate-queries --dev
# or
pnpm add eslint-plugin-react-query-must-invalidate-queries --save-dev
Usage
Add react-query-must-invalidate-queries
to the plugins section of your .eslintrc
configuration file:
{
"plugins": ["react-query-must-invalidate-queries"],
"rules": {
"react-query-must-invalidate-queries/require-mutation-invalidation": "error" // or "warn"
}
}
Rules
require-mutation-invalidation
🔧 This rule enforces that useMutation
hooks include an onSuccess
callback that
calls invalidateQueries
to ensure data consistency.
Why?
When using mutations in React Query, it's important to invalidate related queries after a successful mutation to ensure the UI reflects the latest server state without having to do a lot of mental prep.
This rule helps prevent stale data by ensuring that mutations properly invalidate affected queries.
Rule Details
This rule enforces:
- Presence of an
onSuccess
callback inuseMutation
hooks - The
onSuccess
callback must include a call toinvalidateQueries
✅ Examples of correct code:
useMutation({
mutationFn: updateUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["users"] });
},
});
useMutation({
mutationFn: updateUser,
onSuccess: () => {
const { invalidateQueries } = queryClient;
invalidateQueries({ queryKey: ["users"] });
},
});
useMutation({
mutationFn: updateUser,
onSuccess: async () => {
await someOtherOperation();
await queryClient.invalidateQueries({ queryKey: ["users"] });
},
});
❌ Examples of incorrect code:
useMutation({
mutationFn: updateUser,
});
useMutation({
mutationFn: updateUser,
onSuccess: () => {
console.log("Success!");
},
});
useMutation({
mutationFn: updateUser,
onSuccess: () => {},
});
When Not To Use It
You might want to disable this rule if:
- You have mutations that intentionally don't need to invalidate any queries
- You're handling cache updates through other means like
setQueryData
- You have a specific caching strategy that doesn't require query invalidation
Contributing
Contributions are welcome! Please read our contributing guidelines to get started.
License
MIT