Currently, my code looks like this. When mutation is successful, I have to refetch all the data because tasks
will not be updated. How can I update the client-side tasks
when I submit or delete a task?
const { data: sessionData } = useSession()
const {
data: tasks,
refetch: refetchTasks,
} = api.task.getAll.useQuery(undefined, {
enabled: sessionData?.user !== undefined,
})
const createTask = api.task.create.useMutation({
onSuccess: async () => await refetchTasks(),
})
const createTaskValues = (values: { title: string }) =>
createTask.mutate({ title: values.title })
const deleteTask = api.task.delete.useMutation({
onSuccess: async () => await refetchTasks(),
})
PS
Using useContext()
is better than calling refetch function unless you want to refetch data every time.
const utils = api.useContext()
const createTask = api.task.create.useMutation({
onSuccess: () => utils.task.getAll.invalidate()
})
const createTaskValues = (values: { title: string }) =>
createTask.mutate({ title: values.title })
const deleteTask = api.task.delete.useMutation({
onSuccess: () => utils.task.getAll.invalidate()
})
I figured out the solution by myself. I use tRPC and it provides its own callback function setData()
to mutate cache. tRPC is a wrapper of React-Query though.
This way, when mutation on the database was successful, I can mutate the cache as well.
Now I have to use global state manager like Zustand
less!
const { data: sessionData } = useSession()
const { data: tasks } = api.task.getAll.useQuery(undefined, {
enabled: sessionData?.user !== undefined,
})
const utils = api.useContext()
const createTask = api.task.create.useMutation({
onSuccess: newTask => {
utils.task.getAll.setData(undefined, prevTasks => {
if (prevTasks === undefined) return [newTask]
console.log([...prevTasks, newTask])
return [...prevTasks, newTask]
})
},
})
const createTaskValues = (values: { title: string }) =>
createTask.mutate({ title: values.title })
const deleteTask = api.task.delete.useMutation({
onSuccess: deletedTask => {
utils.task.getAll.setData(undefined, prevTasks => {
const tasksWithoutDeletedTask = prevTasks?.filter(
task => task.id !== deletedTask.id
)
console.log(tasksWithoutDeletedTask)
return tasksWithoutDeletedTask
})
},
})