Next.js 13.4.9 Server Action返回数据及页面刷新跳转方案咨询
Next.js 13.4.9 Server Action 问题解决方案
需求描述
- 向Server Action发送数据,处理后返回字符串,当前通过Cookies获取结果,希望有更简便的方式;
- Server Action执行完成后,实现页面刷新或跳转(类似PHP的实现逻辑)。
现有代码
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(`\n\n\n`); 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, }); }
解决方案
1. 直接获取Server Action返回结果(无需Cookies)
Server Action本身支持直接返回数据,客户端调用时可以直接接收,无需通过Cookies中转。
修改后的TicketAction.ts
"use server"; 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(`\n\n\n`); const result = `You are ${TicketInforamtion.name} and you are ${TicketInforamtion.age.toString()} yo.`; // 直接返回处理结果 return result; }
修改后的page.tsx
"use client"; import React, { useTransition, useState } from "react"; import { SendTicket } from "@/actions/TicketAction"; export default function TicketPage(){ const [isPending, startTransition] = useTransition(); const [ name, setName ] = useState<string>(""); const [ age, setAge ] = useState<number>(0); // 新增state存储Server Action返回的结果 const [result, setResult] = useState<string | null>(null); const handleSubmit = () => { startTransition(async () => { // 直接接收Server Action的返回值 const response = await SendTicket({ name, age }); setResult(response); }); }; return( <main> <form action={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" disabled={isPending}> Valider </button> </form> { isPending ? <span>Loading...</span> : null } {/* 直接渲染返回结果 */} { result && <p>{result}</p> } </main> ) }
2. Server Action执行后实现刷新/跳转
方式一:客户端触发刷新/跳转
在客户端拿到Server Action返回结果后,直接调用浏览器API或Next.js路由工具:
// 在handleSubmit函数中添加逻辑 startTransition(async () => { const response = await SendTicket({ name, age }); setResult(response); // 页面刷新方式1:原生浏览器API window.location.reload(); // 页面刷新方式2:Next.js路由刷新(需导入useRouter) // import { useRouter } from 'next/navigation'; // const router = useRouter(); // router.refresh(); // 跳转到指定页面 // router.push('/success'); });
方式二:Server端直接跳转(类似PHP的header跳转)
使用Next.js内置的redirect函数,在Server Action中直接触发页面跳转:
"use server"; import { redirect } from "next/navigation"; 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(`\n\n\n`); // 完成业务处理后直接跳转 redirect('/success'); }
如果需要传递结果到目标页面,可以结合临时Cookie:
"use server"; import { cookies, redirect } from "next/navigation"; export async function SendTicket(TicketInforamtion: TicketInformationProps){ const result = `You are ${TicketInforamtion.name} and you are ${TicketInforamtion.age.toString()} yo.`; // 设置临时Cookie存储结果 cookies().set({ name: "ResultString", value: result, path: "/success", expires: new Date(Date.now() + 5000), secure: true, }); // 跳转到成功页面 redirect('/success'); }
之后在/success页面读取Cookie并显示结果即可。
内容的提问来源于stack exchange,提问作者raffgiga
相关产品推荐
相关产品推荐

