revalidatePath in server actions causes nothing to happen on success
drewhamlett opened this issue · comments
This worked before I upgraded today. Might be related to #91 ?
"zsa": "^0.3.2",
"zsa-react": "^0.1.4"
// Server action
revalidatePath(`/admin/shop/categories/${categoryId}`)
return {
message: 'Item added',
}
const onClick = async () => {
console.debug('Fired')
const [, err] = await execute({
catalogItemId: Number(item.objectID),
categoryId,
})
console.debug('This works if err')
console.debug('err', err)
if (err) {
toast({
title: 'Error',
description: 'Error adding item',
})
return
}
console.log('Never called if revalidatePath is hit')
toast({
title: 'Item added ✅',
description: 'Item added!',
})
}
Hi, happy to help. Yes, this is probably related to #91. TLDR, is the resolve
of the promise now gets fired once the transition finishes. On prev versions it was weird because it would run your on success however the status would still be pending
because revalidatePath
or redirect
were still running. On the latest versions that you mentioned this is fixed.
I started investigating this but still not able to replicate it. Here is some code I am working with
import IncrementExample from "@/content/docs/examples/introduction/increment-example"
export default async function RevalidatePage() {
// sleep for 5 seconds
await new Promise((resolve) => setTimeout(resolve, 5000))
const randomNumber = Math.floor(Math.random() * 10000)
return (
<div>
<h1>Revalidate Page</h1>
<p>Random number: {randomNumber}</p>
<IncrementExample />
</div>
)
}
"use client"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { useState } from "react"
import { toast } from "sonner"
import { useServerAction } from "zsa-react"
import { incrementNumberAction } from "./actions"
export default function IncrementExample() {
const [counter, setCounter] = useState(0)
const { isPending, execute, data, error, isError } = useServerAction(
incrementNumberAction
)
return (
<Card className="not-prose">
<CardHeader>
<CardTitle>Increment Number</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<Button
disabled={isPending}
onClick={async () => {
const [data, err] = await execute({
number: counter,
})
if (err) {
return
}
toast("got data" + data)
setCounter(data)
}}
>
Invoke action
</Button>
<p>Count:</p>
<div>{isPending ? "saving..." : data}</div>
</CardContent>
</Card>
)
}
"use server"
import { revalidatePath } from "next/cache"
import z from "zod"
import { createServerAction } from "zsa"
export const incrementNumberAction = createServerAction()
.input(
z.object({
number: z.number(),
})
)
.handler(async ({ input }) => {
await new Promise((resolve) => setTimeout(resolve, 500))
revalidatePath("/revalidate", "page")
return input.number + 2
})
Here is a video of the toast showing:
Screen.Recording.2024-06-06.at.8.19.30.AM.mov
Are you possibly doing a redirect
and a revalidatePath
? Going to keep trying to replicate it. Will update when I have it going.
@drewhamlett do you show the isPending
state in your UI? I'm curious if the code gets stuck on isPending. The toast should show right after status goes from "pending" -> "success"
Hi, wanted to check back in and report an update in the latest version of zsa-react@0.1.5. You can now use useServerAction alongside
using the new function executeFormActionHere are the docs
I think this was the issue based on what I have tested. If it is still not working, happy to reopen this. Closing for now.