#Optimistic toggle with useOptimistic and server actions.
1 messages · Page 1 of 1 (latest)
Based on the provided extracts, it seems like you're using the experimental useOptimistic hook from Next.js to implement optimistic updates in your application. This technique is used to enhance user experience by making the app appear more responsive. When an action is invoked, the UI is updated immediately to reflect the expected outcome, instead of waiting for the action's response.
However, the issue you're facing where the optimistic update doesn't come through after the first click might be due to the way you're handling state updates in your onToggleStatus function.
In your Todo component, you're toggling the optimisticStatus state before calling startTransition. This might be causing a race condition where the state update isn't being reflected in the UI immediately.
const onToggleStatus = async () => {
toggleOptimisticStatus(!optimisticStatus);
startTransition(() => toggleStatus(id, !optimisticStatus));
};
One possible solution could be to move the toggleOptimisticStatus call inside the startTransition function. This ensures that the state update and the transition happen simultaneously, which might resolve the issue.
const onToggleStatus = async () => {
startTransition(() => {
toggleOptimisticStatus(!optimisticStatus);
toggleStatus(id, !optimisticStatus);
});
};
Please note that this is a suggestion based on the provided extracts and the actual solution might vary depending on the rest of your codebase and the specific behavior of the useOptimistic hook and startTransition function.
For more information, you can refer to the Next.js documentation on Server Actions (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions).
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@shell stratus kapa.ai is still learning and improving, please let us know how it did by reacting below
@bitter kettle I believe it's because I'm revalidating the path's data every time the toggle is clicked? Beacause here's what toggleStatus looked like at first when I was facing the problem i descrbed:
export const toggleStatus = async (todoId: string, newStatus: boolean) => {
const supabase = createRouteHandlerClient({ cookies });
await supabase
.from("todos")
.update({ completed: newStatus })
.eq("id", todoId);
revalidatePath("/todos");
};
Now I modified this function such that the revalidation will only take place when an error occurs:
export const toggleStatus = async (todoId: string, newStatus: boolean) => {
const supabase = createRouteHandlerClient({ cookies });
try {
await supabase
.from("todos")
.update({ completed: newStatus })
.eq("id", todoId);
} catch (error) {
revalidatePath("/todos");
console.error(error);
alert("Something worng happened! Please try again");
}
};
This made the toggle button TodoStatus behave more as expected.
Let me check the knowledge base for you. One moment! :books:
Yes, you're correct. The issue you were facing was likely due to the fact that you were revalidating the data at the path /todos every time the toggleStatus function was called. This means that every time you clicked the toggle, Next.js was instructed to re-fetch the data from the server, which could have caused a delay in updating the UI.
By moving the revalidatePath("/todos") call into the catch block, you're now only revalidating the data when an error occurs during the update operation. This means that under normal circumstances, when no error occurs, the UI can update immediately without having to wait for data revalidation.
Here's your updated toggleStatus function:
export const toggleStatus = async (todoId: string, newStatus: boolean) => {
const supabase = createRouteHandlerClient({ cookies });
try {
await supabase
.from("todos")
.update({ completed: newStatus })
.eq("id", todoId);
} catch (error) {
revalidatePath("/todos");
console.error(error);
alert("Something wrong happened! Please try again");
}
};
This approach aligns with the error handling and revalidation strategy mentioned in the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating). If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@shell stratus kapa.ai is still learning and improving, please let us know how it did by reacting below