You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中Server Action能否同时返回响应并重验证路径?

在Next.js Server Action中调用revalidatePath时能否同时返回响应对象?

我在实现addTodo Server Action(位于app/_actions/todo.tsx)时,希望在调用revalidatePath('/')重验证路径的同时返回响应对象,但遇到了不稳定的问题:成功处理请求后,useFormState钩子返回的formState对象有时包含todo属性,有时不包含。

addTodo Server Action代码

export async function addTodo(prevState: any, formData: FormData) {
    const errors: {
        title?: string;
        description?: string;
    } = {};
    const title = formData.get('title')?.toString();
    const description = formData.get('description')?.toString();
    
    // Validate title and description

    if(errors.title || errors.description) {
        return { errors };
    }
    
    await dbConnect();

    const todo = new Todo({
        title,
        description
    });

    await todo.save();

    revalidatePath('/');

    return { todo: { title, description } };
}

更新

我发现app根目录下的loading.tsx文件会破坏缓存失效行为,移除该文件后,Server Action的revalidatePath与返回响应体的功能恢复正常,但我需要保留loading.tsx来显示路径/上待办列表的加载状态,寻求相关解决办法。

项目文件结构

app目录下包含:

  • page.tsx
  • loading.tsx
  • _components/Todos/TodoList.tsx
  • _actions/todos.tsx、_actions/todo.tsx

以下是各关键文件代码:

app/page.tsx

import { Metadata } from 'next';
import TodoList from './_components/Todos/TodoList';

export const metadata: Metadata = {
    title: 'Todo App',
    description: 'Todo application for practicing Next.js',
};

export default function Home() {
    return (
        <TodoList />
    );
}

app/loading.tsx

export default function Loading() {
    return <p className="text-yellow-400">Loading...</p>;
}

app/_components/Todos/TodoList.tsx

'use server';
import { fetchTodos } from '@/app/_actions/todos';
import TodoListItem from './TodoListItem';

export default async function TodoList() {
    const fetchedTodos = await fetchTodos();

    if (!fetchedTodos.length) {
        return <p className="text-red-500">No todos were found!</p>;
    }

    return (
        <ul>
            {fetchedTodos.map((todo) => (
                <TodoListItem key={todo._id.toString()} todo={todo} />
            ))}
        </ul>
    );
}

app/_actions/todos.tsx中的fetchTodos函数

export async function fetchTodos() {
    await dbConnect();

    const todos = await Todo.find().sort({ createdAt: 'desc' });

    return todos;
}

内容的提问来源于stack exchange,提问作者M. Çağlar TUFAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:41:20