如何在 Nextjs 13 服务器端组件中提交后清除表单?

Ale*_*lex 3 next.js next.js13

我不知道如何在服务器端组件提交后清除表单字段,因为它无法使用挂钩。提交工作正常,但似乎在调用完成后无法清除字段。这里怎么解决这个问题呢?

我在此应用程序中有一个向 API 提交数据的表单:

页面.tsx:

import { Product } from '@/typings'

import Form from './components/Form'

export default async function Home() {

  const res = await fetch('https://64c0eea9fa35860bae9fa770.mockapi.io/products', {
    cache: 'no-cache',
    next: {
      tags: ['products']
    }
  })

  const products: Product[] = await res.json()


  return (
    
    <main className="flex min-h-screen flex-col items-center justify-between  text-3xl font-bold">
      <h1 className='mt-2'> Product Warehouse</h1>

      <h2 className='font-bold '>List of Products</h2>

      <div className='flex flex-wrap '>
        {products.map((product) => (
          <div
           key={product.id} className='p-5 shadow '>

          <p>{product.product}</p>
          <p>${product.price}</p>
          </div>
        ))}
      </div>

      < Form />

    </main>
  )
}
Run Code Online (Sandbox Code Playgroud)

这发生在这里:

服务器操作.ts:

"use server"

import { Product } from "@/typings"
import { revalidateTag } from "next/cache"

export const addProductToDB = async (e:FormData) => {
    
    const product = e.get("product")?.toString()
    const price = e.get("price")?.toString()

    if (!product || !price) return 

    const newProduct: Product = {
      product: product,
      price: price
    }

    await fetch('https://64c0eea9fa35860bae9fa770.mockapi.io/products', {
      method: 'POST',
      body: JSON.stringify(newProduct),
      headers: { 'Content-Type': 'application/json'},
      
      
    })
    revalidateTag('products')
    
    
}
Run Code Online (Sandbox Code Playgroud)

这是表单本身:Form.tsx:

"use client"

import { addProductToDB } from "@/actions/serverActions"

function Form() {

  return (
    <form action={addProductToDB} id="myForm" className='flex flex-col gap-5 max-w-xl mx-auto p-5'>
        <input type="text" 
          name='product'
         
          placeholder='Enter Product Name'
          className='border border-gray-300 p-2 rounded-md'
          
        />
        <input type="text" 
         
        
         name='price'
         placeholder='Enter Price'
         className='border border-gray-300 p-2 rounded-md'
        />
      
        {/* < AddButton /> */}
        <button type="submit" className='border bg-blue-500 text-white p-2 rounded-md'>
            Add
        </button>
      </form>
  )
}

export default Form
Run Code Online (Sandbox Code Playgroud)

Vic*_* Fu 8

因为你的Form是客户端组件。您可以使用钩子引用来useRef控制您的<form>. 以下是我的工作示例:

"use client";

import { actionAddItem } from "@/app/(main)/administration/items/actions";
import { useRef } from "react";
import { experimental_useFormStatus as useFormStatus } from "react-dom";

const ItemForm = () => {
  const { pending } = useFormStatus();
  const ref = useRef<HTMLFormElement>(null);

  return (
    <form
      ref={ref}
      className="flex flex-col items-start bg-white rounded-lg p-8 shadow-md"
      action={async (formData) => {
        await actionAddItem(formData);
        ref.current?.reset();
      }}
    >
      <label className="mb-2 text-lg font-semibold" htmlFor="title">
        Title
      </label>
      <input
        className="border border-gray-300 p-2 rounded-lg mb-6 focus:ring focus:ring-blue-200 w-full"
        type="text"
        name="title"
        id="title"
      />

      <label className="mb-2 text-lg font-semibold" htmlFor="description">
        Description
      </label>
      <input
        className="border border-gray-300 p-2 rounded-lg mb-6 focus:ring focus:ring-blue-200 w-full"
        type="text"
        name="description"
        id="description"
      />

      <button
        className="bg-blue-500 text-white rounded px-4 py-2 hover:bg-blue-600"
        type="submit"
        disabled={pending}
      >
        Add
      </button>
    </form>
  );
};

export default ItemForm;
Run Code Online (Sandbox Code Playgroud)

提交表格后,只需使用ref.current?.reset();清除您的表格即可。