Handling Query Invalidation Correctly
Provide an example of proper query invalidation using React Query to ensure data consistency across components and browser tabs.
import { useQuery, useMutation, useQueryClient } from 'react-query';
Import necessary hooks from react-query.
const fetchTodos = async () => {
const response = await fetch('/api/todos');
if (!response.ok) {
throw new Error('Fetching todos failed');
}
return response.json();
};
Define a function to fetch todos from an API.
const Todos = () => {
const queryClient = useQueryClient();
const { data: todos, isLoading, error } = useQuery('todos', fetchTodos);
if (isLoading) return 'Loading...';
if (error) return 'An error occurred: ' + error.message;
return (
<ul>{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}</ul>
);
};
Component that uses useQuery to fetch and display a list of todos.
const addTodo = async (text) => {
const response = await fetch('/api/todos', {
method: 'POST',
body: JSON.stringify({ text }),
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error('Adding todo failed');
}
return response.json();
};
Define a function to add a todo by sending a POST request to an API.
const AddTodoForm = () => {
const queryClient = useQueryClient();
const { mutate } = useMutation(addTodo, {
onSuccess: () => {
// Invalidate and refetch
queryClient.invalidateQueries('todos');
},
});
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const text = formData.get('text');
mutate(text);
};
return (
<form onSubmit={handleSubmit}>
<input name="text" type="text" required />
<button type="submit">Add Todo</button>
</form>
);
};
Component for adding a new todo. It uses the useMutation hook to add the todo and invalidates the todos query on successful mutation to fetch the updated list.