Skip to content

Instantly share code, notes, and snippets.

@ilxanlar
Last active April 5, 2021 14:38
Show Gist options
  • Save ilxanlar/8b1afa2ac4939288cf9ba194eacf0b62 to your computer and use it in GitHub Desktop.
Save ilxanlar/8b1afa2ac4939288cf9ba194eacf0b62 to your computer and use it in GitHub Desktop.
import React from 'react'
import { useMutation, useQuery, useQueryClient } from 'react-query'
const fetchTodos = async () => {
// Get todos list from the API
}
const markAsDone = async (id) => {
// Send a request to the API
}
export default function MyTodoApp() {
const queryClient = useQueryClient()
const query = useQuery('todo', fetchTodos)
const mutation = useMutation(markAsDone, {
// When mutate is called:
onMutate: async (id) => {
// Cancel any outgoing refetches of todos query
await queryClient.cancelQueries('todos')
// Snapshot the previous value
const snapshot = queryClient.getQueryData('todos')
// Optimistically update to the new value
queryClient.setQueryData('todos', prev => prev.map(item => {
if (item.id === id) {
return { ...item, done: true }
} else {
return item
}
}))
// Return a context object with the snapshotted value
return { snapshot }
},
// If the mutation fails, use the context returned from onMutate to roll back
onError: (err, newTodo, context) => {
queryClient.setQueryData('todos', context.snapshot)
},
// Always refetch after error or success:
onSettled: () => {
queryClient.invalidateQueries('todos')
},
})
const handleMarkAsDone = todo => {
mutation.mutate(todo.id)
}
const todos = query.data || []
return (
<ul>
{todos.map(todo => (
<li>
<span>{todo.title}</span>
{todo.done ? (
<span>Done</span>
) : (
<button onClick={() => handleMarkAsDone(todo)}>
Mark as Done
</button>
)}
</li>
))}
</ul>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment