Is there a way to return data and refresh the page with a server action and Next.js – Next.js

by
Ali Hasan
next.js

Quick Fix: To return data and refresh the page, use the experimental_useFormState hook from React.dom. This hook allows you to get the return data from a server action and update the state accordingly. Once the data is returned, you can use it to refresh the page.

The Problem:

In a Next.js application, there is a requirement to return data and refresh the page after a server action is performed. The current approach uses cookies to retrieve the result data, but a more efficient solution is desired. Additionally, the need to refresh or redirect the page after the server action is also present.

The Solutions:

Solution 1: {Using useFormState hook}

You can get the return data from a server action using the `useFormState` hook from `react-dom`. Here’s how you can do it:

  • Import `useFormState` from `react-dom`.
    import { experimental_useFormState as useFormState } from 'react-dom'
    
  • Replace `useState` with `useFormState` in your component.
    const [state, formAction] = useFormState(action)
    
  • In the return value from `useFormState`, the `state` will be undefined or set to an initial value until a return value is received from the server action.

Solution 2: Using a Form-State Hook and `revalidatePath`

Next.js version 14 introduces the useFormState() hook, which allows for easy form handling in server actions. With this hook, you can:

  1. Handle form submission and validation on both the client and server side.
  2. Mutate the form data in your server action and return an object.
  3. Use the revalidatePath('/') function after mutating the data to ensure that the component that sent the form data is re-rendered.

By returning an object in your server action, you trigger the re-rendering of the component that sent the form data. The revalidatePath('/') function informs Next.js that the page is dynamic and should not be cached. As a result, the page will be re-rendered on every request, ensuring that the latest data is displayed.

Solution 3: Using Next.js Server Actions

Next.js Server Actions allow you to execute server-side code directly within a component function. To use Server Actions, you must enable them in your next.config.js file:

const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

To use Server Actions, you can add the "use server" directive to the top of the component function body. For example:

// This will refresh the page
import { revalidatePath } from "next/cache";

export async function SendTicket(TicketInforamtion: TicketInformationProps) {
  "use server";
  const result = `You are ${TicketInforamtion.name} and you are ${TicketInforamtion.age.toString()} yo.`;
  cookies().set({
    name: "ResultString",
    value: result,
    path: "/ticket",
    expires: new Date(Date.now() + 1000 * 1),
    secure: true,
  });
  revalidatePath("/route");
}

However, it’s important to note that Server Actions should primarily be used for server-side data mutation or tasks. They are not intended to return values that can be used directly within the component.

Q&A

Can I get the return data from the server action ? And can I refresh or redirect after the server action ?

For Next.js v.14:

You have to use useFormState() hook and after mutating the data in your action server and return an object which will cause the component that sent the form data to rerender (it’s like a refresh).

Note: You have to use revalidatePath('/') after mutating the data to tell Next.js that the component that sent the form data is a dynamic page so it will re-render on new requests (when it will re-render because of useFormState hook) instead of serving a cached version of the page.

Video Explanation:

The following video, titled "Server Actions: NextJS 13.4's Best New Feature - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Being a web developer for 15+ years, I'm confident that the best way to build apps is building a decoupled API ...