T
TanStack•4y ago
wise-white

Im trying to create a custom Hook with useMutation

this is my custom hook which im exporting into my todo component, i want to call mutate on the hook via a button click. but the hook returns a promise and mutate is no available, can anyone help? hook
export default async function useUpdateUsers(client: any) {
return useMutation(
(newUser: any, client: any) => {
return axios.post(
'https://api-for-personal-projects.vercel.app/api/contacts',
newUser
)
},
{
onMutate: async (newUser) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await client.cancelQueries(['users'])

// Snapshot the previous value
const previousUsers = client.getQueryData(['users'])

// Optimistically update to the new value
client.setQueryData(['users'], (old: any) => [newUser, ...old])

// Return a context object with the snapshotted value
return { previousUsers }
},
// If the mutation fails, use the context returned from onMutate to roll back
onError: (err, newUser, context: any) => {
client.setQueryData(['users'], context.previousUsers)
},
// Always refetch after error or success:
onSettled: () => {
client.invalidateQueries(['users'])
}
}
)
}
export default async function useUpdateUsers(client: any) {
return useMutation(
(newUser: any, client: any) => {
return axios.post(
'https://api-for-personal-projects.vercel.app/api/contacts',
newUser
)
},
{
onMutate: async (newUser) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await client.cancelQueries(['users'])

// Snapshot the previous value
const previousUsers = client.getQueryData(['users'])

// Optimistically update to the new value
client.setQueryData(['users'], (old: any) => [newUser, ...old])

// Return a context object with the snapshotted value
return { previousUsers }
},
// If the mutation fails, use the context returned from onMutate to roll back
onError: (err, newUser, context: any) => {
client.setQueryData(['users'], context.previousUsers)
},
// Always refetch after error or success:
onSettled: () => {
client.invalidateQueries(['users'])
}
}
)
}
todo component
<div className={className}>
<button
className="my-2 font-bold"
onClick={() =>
useUpdateUsers.mutate({
id: data.slice(0)[0].id + 1, // - get first id and add 1
firstName: 'davids',
lastName: 'Adesanya',
dateOfBirth: '1985-03-15T00:00:00',
school: 'Torquay Boys',
phoneNumber: '01803 123456'
})
}
>
Add User
</button>
<div className={className}>
<button
className="my-2 font-bold"
onClick={() =>
useUpdateUsers.mutate({
id: data.slice(0)[0].id + 1, // - get first id and add 1
firstName: 'davids',
lastName: 'Adesanya',
dateOfBirth: '1985-03-15T00:00:00',
school: 'Torquay Boys',
phoneNumber: '01803 123456'
})
}
>
Add User
</button>
10 Replies
adverse-sapphire
adverse-sapphire•4y ago
Remove the async on the function defining the hook ?
wise-white
wise-whiteOP•4y ago
okay ill do that
wise-white
wise-whiteOP•4y ago
No description
No description
wise-white
wise-whiteOP•4y ago
figured it out
optimistic-gold
optimistic-gold•4y ago
you can't call the hook in the click handler. You need to call the hook at the top level, then invoke mutate onClick
wise-white
wise-whiteOP•4y ago
this worked, but is there a better way of doing this?
wise-white
wise-whiteOP•4y ago
No description
wise-white
wise-whiteOP•4y ago
thank you for all the help
optimistic-gold
optimistic-gold•4y ago
what would you need to be "better" ? this is the way 🙂
wise-white
wise-whiteOP•4y ago
nothing at all, you are right.

Did you find this page helpful?