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

如何将Ref传递给Server Action?表单重置问题求助

解决Server Action中无法通过Ref重置表单的问题

Server Action是运行在服务器端的代码,而表单的Ref是客户端的DOM元素引用,服务器根本没法直接访问客户端的DOM,所以你在Action里写ref.current?.reset()肯定没用。

下面给两种可行的解决办法:

方案一:用useFormState监听提交结果

通过useFormState获取Server Action的返回状态,在客户端判断提交成功后重置表单。

修改Server Action代码

让Action返回提交状态:

// actions/createVm.js
'use server'

export async function createVm(prevState, formData) {
    try {
        await prisma.vm.create({
            data: {
                name: formData.get("DisplayName"),
                ip: formData.get("IpAddress"),
                group: {
                    connect: { name: formData.get("group") }
                }
            }
        })
        // 提交成功返回成功状态
        return { success: true }
    } catch (err) {
        return { success: false, error: err.message }
    }
}

修改表单组件代码

在客户端组件里用useFormState接收Action的返回值,成功后调用表单reset:

// app/createVm/page.jsx
'use client'

import ButtonForm from "./button"
import { useRef, useEffect } from "react"
import { createVm } from "@/actions/createVm"
import { useFormState } from 'react-dom'

export default function Form({ children }) {
  const formRef = useRef(null)
  // 用useFormState绑定Action,prevState是上一次的返回值
  const [submitState, formAction] = useFormState(createVm, { success: false })

  // 监听提交状态变化,成功就重置表单
  useEffect(() => {
    if (submitState.success) {
      formRef.current?.reset()
    }
  }, [submitState.success])

  return(
      <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
          <form className="space-y-6" action={formAction} ref={formRef}>
              { children }
              <ButtonForm />
          </form>
      </div>
  )
}

方案二:手动处理表单提交(不推荐,但简单)

如果不想用useFormState,可以手动阻止默认提交,调用Action后直接重置表单:

// app/createVm/page.jsx
'use client'

import ButtonForm from "./button"
import { useRef } from "react"
import { createVm } from "@/actions/createVm"

export default function Form({ children }) {
  const formRef = useRef(null)

  const handleSubmit = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    await createVm(formData)
    // 提交完成后直接重置
    formRef.current?.reset()
  }

  return(
      <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
          <form className="space-y-6" onSubmit={handleSubmit} ref={formRef}>
              { children }
              <ButtonForm />
          </form>
      </div>
  )
}

这种方式虽然简单,但会失去Server Action自带的一些特性(比如自动表单状态管理、pending状态处理),所以更推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:56:15