How to I trigger data refresh on a parent RSC when a child triggers a server action?
Answered
WebDevSayantan posted this in #help-forum
I have an Invoices component(RSC) which shows a list of InvoiceCard components(RSC). The InvoiceCard component contains a DeleteButton(React Client Component) that invokes a server action to delete an invoice. How to I refresh the list of invoices, fetched in the top level Invoices Component when I call this delete server action?
Invoices & InvoiceCard component:
DeleteInvoice Server Action
DeleteButton Client Component
Invoices & InvoiceCard component:
export default async function Invoices({
params,
}: { params: { homestay: string } }) {
// how do I update this list when delete server action is triggered from it's child component?
const invoices = await getAllInvoices(params.homestay);
return (
<div>
{invoices.map((invoice) => (
<InvoiceCard key={invoice.id} invoice={invoice} />
))}
</div>
);
}
export default async function InvoiceCard({
invoice,
}: { invoice: InvoiceCardProps }) {
return (
<Card>
{/* Divs showing invoice data */}
<CardFooter>
{invoice.id && (
<DeleteButton
invoiceId={invoice.id}
deleteInvoice={deleteInvoiceAction}
/>
)}
</CardFooter>
</Card>
);
}DeleteInvoice Server Action
"use server";
// imports and stuff
export async function deleteInvoiceAction(invoiceId: number) {
const deleted = await deleteInvoice(invoiceId); // db call to delete invoice
return deleted.length > 0 ? deleted[0].id : null;
}DeleteButton Client Component
// the server action is passed as prop from invoiceCard component
export default function DeleteButton({
invoiceId,
deleteInvoice,
}: any) {
const [open, setOpen] = useState(false);
return (
{* 'Server action which was send via prop is triggered' *}
<Button variant="destructive"
onClick={async () => {
await deleteInvoice(invoiceId);
setOpen(false);
}}
> Delete
</Button>
);
}Answered by Ray
use
revalidatePath in server action"use server";
// imports and stuff
export async function deleteInvoiceAction(invoiceId: number) {
const deleted = await deleteInvoice(invoiceId); // db call to delete invoice
if (deleted.length) {
revalidatePath("/invoices")
}
return deleted.length > 0 ? deleted[0].id : null;
}2 Replies
@WebDevSayantan I have an Invoices component(RSC) which shows a list of InvoiceCard components(RSC). The InvoiceCard component contains a DeleteButton(React Client Component) that invokes a server action to delete an invoice. How to I refresh the list of invoices, fetched in the top level Invoices Component when I call this delete server action?
**Invoices & InvoiceCard component:**
typescript
export default async function Invoices({
params,
}: { params: { homestay: string } }) {
// how do I update this list when delete server action is triggered from it's child component?
const invoices = await getAllInvoices(params.homestay);
return (
<div>
{invoices.map((invoice) => (
<InvoiceCard key={invoice.id} invoice={invoice} />
))}
</div>
);
}
export default async function InvoiceCard({
invoice,
}: { invoice: InvoiceCardProps }) {
return (
<Card>
{/* Divs showing invoice data */}
<CardFooter>
{invoice.id && (
<DeleteButton
invoiceId={invoice.id}
deleteInvoice={deleteInvoiceAction}
/>
)}
</CardFooter>
</Card>
);
}
**DeleteInvoice Server Action **
typescript
"use server";
// imports and stuff
export async function deleteInvoiceAction(invoiceId: number) {
const deleted = await deleteInvoice(invoiceId); // db call to delete invoice
return deleted.length > 0 ? deleted[0].id : null;
}
**DeleteButton Client Component**
typescript
// the server action is passed as prop from invoiceCard component
export default function DeleteButton({
invoiceId,
deleteInvoice,
}: any) {
const [open, setOpen] = useState(false);
return (
{* 'Server action which was send via prop is triggered' *}
<Button variant="destructive"
onClick={async () => {
await deleteInvoice(invoiceId);
setOpen(false);
}}
> Delete
</Button>
);
}
use
revalidatePath in server action"use server";
// imports and stuff
export async function deleteInvoiceAction(invoiceId: number) {
const deleted = await deleteInvoice(invoiceId); // db call to delete invoice
if (deleted.length) {
revalidatePath("/invoices")
}
return deleted.length > 0 ? deleted[0].id : null;
}Answer