skip to Main Content

I’m trying to create a webapp with Next.js (13.4.9) and I would use the server action. With the server action, I would send data to my action, this action is going to treat this data and return me a string. The only way I’ve found so far to get the result data from the action is with the cookies. So is there an other way (easier) I can get the data from the server action ? And I would also refresh the page or redirect the user to an other page just after the server action (like with php). So how can I do a refreshing or a redirect after the server action ?

Here is my actual code :

// page.tsx

"use client";
import React, { useTransition, useState } from "react";
import { SendTicket } from "@/actions/TicketAction";
import Cookies from "js-cookie";

export default function TicketPage(){

    const [isPending, startTransition] = useTransition();
    const [ name, setName ] = useState<string>("");
    const [ age, setAge ] = useState<number>(0);

    

    return(
        <main>
                <form action={() => startTransition(() => SendTicket({
                    name: name, age: age
                }))}>
                    <input type="text" value={name} onChange={(e) => setName(e.target.value)}
                    placeholder="Your name" />
                    <input type="number" value={age} onChange={(e) => setAge(parseInt(e.target.value))}
                    placeholder="Your age" />
                    <button type="submit">
                        Valider
                    </button>
                </form>
                { isPending ? <span>Loading...</span> : <></> }
                <Result />
        </main>
    )
}

function Result(){
    const ResultString = Cookies.get("ResultString");
    Cookies.remove("ResultString");

    return(
        <p>{ResultString?.toString()}</p>
    )
}
// TicketAction.ts

"use server";
import { cookies } from "next/headers";

export interface TicketInformationProps {
    name: string;
    age: number;
}

export async function SendTicket(TicketInforamtion: TicketInformationProps){
    console.log(`[NEW TICKET]`);
    console.log(`Nom: ${TicketInforamtion.name}`);
    console.log(`Age: ${TicketInforamtion.age.toString()}`);
    console.log(`nnn`);

    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,

    });
}

2

Answers


  1. To simplify the process of getting data from the server action in Next.js and to handle page refreshing or redirection after the server action, you can use the getServerSideProps function and leverage the res.redirect method. Here’s an updated version of your code:

    // page.tsx
    
    import { useRouter } from 'next/router';
    import React, { useState } from 'react';
    import { SendTicket } from '@/actions/TicketAction';
    
    export default function TicketPage() {
      const router = useRouter();
      const [name, setName] = useState('');
      const [age, setAge] = useState(0);
    
      const handleSubmit = async (e) => {
        e.preventDefault();
        try {
          await SendTicket({ name, age });
          // Redirect to another page after the server action
          router.push('/success');
        } catch (error) {
          console.log(error);
        }
      };
    
      return (
        <main>
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Your name"
            />
            <input
              type="number"
              value={age}
              onChange={(e) => setAge(parseInt(e.target.value))}
              placeholder="Your age"
            />
            <button type="submit">Valider</button>
          </form>
        </main>
      );
    }
    
    // TicketAction.ts
    
    export interface TicketInformationProps {
      name: string;
      age: number;
    }
    
    export async function SendTicket(TicketInformation: TicketInformationProps) {
      console.log(`[NEW TICKET]`);
      console.log(`Nom: ${TicketInformation.name}`);
      console.log(`Age: ${TicketInformation.age.toString()}`);
      console.log(`nnn`);
    
      // Process the data and return the result
      const result = `You are ${TicketInformation.name} and you are ${TicketInformation.age.toString()} yo.`;
    
      return result;
    }
    

    With these updates:

    1. In page.tsx, the handleSubmit function is modified to handle the form submission. It prevents the default form submission behavior, calls the SendTicket function asynchronously, and then redirects to the /success page using router.push('/success').

    2. In TicketAction.ts, the SendTicket function processes the data and returns the result directly instead of setting cookies. The result will be passed as a prop to the /success page.

    To handle the result and display it on the /success page, you can modify the /success page as follows:

    // success.tsx
    
    import React from 'react';
    import { GetServerSideProps } from 'next';
    
    interface SuccessProps {
      result: string;
    }
    
    export default function SuccessPage({ result }: SuccessProps) {
      return <p>{result}</p>;
    }
    
    export const getServerSideProps: GetServerSideProps<SuccessProps> = async () => {
      // Fetch the result from the server action
      const result = await SendTicket({ name: 'example', age: 25 });
    
      // Pass the result as a prop to the SuccessPage
      return {
        props: {
          result,
        },
      };
    };
    

    In the updated /success page, the getServerSideProps function fetches the result by calling the SendTicket function with example data. The result is then passed as a prop to the SuccessPage, which can be accessed and displayed using props.result.

    By using getServerSideProps and redirecting the user to another page, you can simplify the process of getting data from the server action, refresh the page after the action, and redirect the user to a different page as needed.

    Login or Signup to reply.
  2. server actions are still experimental. you should have this setup in next.config.js

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

    "use server" directive should be placed at the top of the component function body.

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

    server actions are used to mutate data on the server or do server specific tasks. I do not think that you can have a return value and use it inside the component

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search