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

Next.js 13.4服务器操作返回值无法获取问题求助

问题解决:Next.js 13服务器操作返回值获取与类型错误修复

一、TypeScript类型错误原因及修复

你遇到的TS2322类型错误,核心原因是:

  • 表单的action属性默认期望字符串类型(传统URL),直接传入服务器操作函数不符合类型要求;
  • 服务器操作若定义在客户端组件中,会导致执行环境不匹配('use server'指令需在服务器组件或独立文件中使用)。

修复步骤:

  1. 将服务器操作移至独立文件或服务器组件:
    创建app/actions.ts文件,存放服务器操作逻辑:

    'use server';
    
    import { redirect } from 'next/navigation';
    
    export async function validation(prevState: { error?: string }, formData: FormData) {
      const data = formData.get("str");
      const str = JSON.stringify(data).replace(/['"]+/g, '');
    
      if (!str) {
        return { error: "String is Required" };
      } else if (!(/^[a-zA-Z0-9]{8}$/).test(str)) {
        return { error: "Invalid String Format" };
      }
    
      await redirect(`/scan-code=${str}`);
      return null;
    }
    

    注意:服务器操作函数的第一个参数为前一次状态,用于接收和更新表单状态。

  2. 在客户端组件中使用useFormState包装操作:
    客户端组件中通过useFormState获取符合类型要求的表单action:

    'use client';
    
    import { useFormState } from 'react-dom';
    import { validation } from './actions';
    
    export default function ValidateForm() {
      // 初始状态为空对象,useFormState返回[当前状态, 包装后的表单action]
      const [formState, formAction] = useFormState(validation, {});
    
      return (
        <form action={formAction}>
          <label style={{ color: formState.error ? 'red' : 'black' }}>
            {formState.error && formState.error}
          </label>
          <input 
            placeholder="Enter String Here"
            required 
            name="str"
          />
          <button type="submit">Submit</button>
        </form>
      );
    }
    

二、Next.js中替代Remix钩子的方案

Next.js官方提供useFormState和useFormStatus钩子,完全可以替代Remix的useFetcher和useActionData:

  • useFormState:直接获取服务器操作的返回值(如错误信息),无需上下文、本地存储或数据库持久化,是处理表单状态反馈的核心方案;
  • useFormStatus:可选搭配,用于获取表单提交状态(如是否正在提交),示例:
    'use client';
    
    import { useFormStatus } from 'react-dom';
    
    function SubmitButton() {
      const { pending } = useFormStatus();
      return (
        <button type="submit" disabled={pending}>
          {pending ? 'Submitting...' : 'Submit'}
        </button>
      );
    }
    

内容的提问来源于stack exchange,提问作者ricarn1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:27:42