I would love a short code review of "my" implementation of optimistic ui patterns. I'm using SWR, immer and a custom fetch hook to do most of the heavy lifting. However, I'm not really sure if this is indeed the way to do it. Especially when it comes to asigning a temporary id to the optimistically generated item. Shouldn't I clear it somewhere? May it cause issues?
const spawn = async flavour => {
const payload = {
planId: flavour.id,
name: 'test',
description: '',
}
mutate(
'/account/instances',
produce(draft => {
draft.push({
...payload,
id: uuid(),
plan: {name: flavour.name},
state: {status: 'PENDING'},
image: {name: flavour.image.name},
})
}),
false
)
mutate(
'/account/instances',
await doFetch('/account/instances', 'post', payload)
)
}
Thanks!
Your code seems correct to me. It will update optimistically the UI, fetch data from the backend, and update again the UI with that data if it differs.
Regarding the generated id, it really depends on what you do with it. If you do nothing important it will probably be ok as that id will be overwritten with the real one when the backend replies. But it may cause problems if you display it to the user (the user will see it being updated), or even worse if you provide an action based on it.
I would also like to draw your attention on the fact that the reply may fail for network reasons, or reasons related to a problem on backend side. In that case, if you receive just an error or never receive any reply, your UI will remain in an incorrect state until the next successful fetch made by swr. To avoir this kind of problem, you may be interested in use-mutation. It's a small lib designed to be used with swr to rollback the optimistically updated data in case of error.