With the new useOptimistic hook I wanted to use it for more then just simple setState calls and rather have it work for create, update and delete calls. While this is a new hook and there are not a lot of code out there showing use cases I wanted an opinion on if there is a better way to do it then my below code.
const [optimisticTasks, setOptimisticTasks] = useOptimistic(tasks, (state, { action, task }: { action: string, task: Task }) => {
if (action === 'delete') return state.filter(({ id }) => id !== task.id)
if(action === 'update') return state.map(t => t.id === task.id ? task : t)
return [...state, task]
})
I apologize for this not being a 'proper' stack overflow question but I just want to get some opinions on if this is a good way to go about using this hook for this task.
Yes, I think your code is spot on. useOptimistic
accepts a reducer as a second argument which is what you are passing it.
A common pattern is using a switch statement within a reducer, so something like this:
const [optimisticTasks, setOptimisticTasks] = useOptimistic(
tasks,
(state, { action, task }: { action: string; task: Task }) => {
switch (action) {
case "delete":
return state.filter(({ id }) => id !== task.id);
case "update":
return state.map((t) => (t.id === task.id ? task : t));
default:
return [...state, task];
}
},
);
Another thing I can think of is defining the reducer as a separate function and then passing it to useOptimistic
to improve readability, especially as it starts to grow.