如何在nextJs中访问服务器上的表单值?

问题描述 投票:0回答:1

我无法正确地将表单数据传递到 nextJS 中的 api 端点。我正在使用 formik 和 yup 来创建表单并验证数据。当我将数据记录到客户端的控制台时,我在控制台中看到用户输入。但是,我在服务器上未定义这些值。另外,当我将请求对象打印到控制台时,正文为空,并且 bodyUsed 设置为 false。 这是我的客户端组件:

"use client";
import React, { useState } from "react";
import { useFormik } from "formik";
import * as yup from "yup";
import FormGroup from "../(components)/FormGroup";

const Contact = () => {
  const [loading, setLoading] = useState(false);
  const [processed, setProcessed] = useState(false);

  const formik = useFormik({
    initialValues: {
      firstName: "",
      lastName: "",
      email: "",
      message: "",
    },
    onSubmit: async (values) => {
      try {
        setLoading(true);
        const res = await fetch("http://localhost:3000/api/Contact", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(values, null, 2),
        });
        console.log(res);

        if (res.ok) {
          setProcessed(true);
          setLoading(false);
        }
      } catch (error) {
        console.log("Error processing message: ", error);
        setLoading(false);
      }
    },
    validationSchema: yup.object({
      firstName: yup.string().trim().required("First Name is required"),
      lastName: yup.string().trim().required("Last Name is required"),
      email: yup
        .string()
        .email("Must be a valid email")
        .required("Email is required"),
      message: yup.string().trim().required("Message is required"),
    }),
  });

  return (
    <div className="min-h-screen flex flex-col justify-start  items-center w-full mx-auto mt-24">
      {processed && (
        <p className="text-lg font-semibold justify-self-center">
          Thank you for contacting us! We'll get back to you shortly.
        </p>
      )}
      {!processed && (
        <form
          className="flex flex-col space-y-2"
          onSubmit={formik.handleSubmit}
        >
          <div className="w-full flex space-x-2">
            <div className="flex flex-col">
              <FormGroup
                inputLabel={"First Name:"}
                placeholder={"First Name"}
                name={"firstName"}
                value={formik.values.firstName}
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
              />
              {formik.errors.firstName && (
                <p className="text-sm text-pink-600 mt-1">
                  {formik.errors.firstName}
                </p>
              )}
            </div>
            <div className="flex flex-col">
              <FormGroup
                inputLabel={"Last Name:"}
                placeholder={"Last Name"}
                name={"lastName"}
                value={formik.values.lastName}
                onChange={formik.handleChange}
                onBlur={formik.handleBlur}
              />
              {formik.errors.lastName && (
                <p className="text-pink-600 text-sm mt-1">
                  {formik.errors.lastName}
                </p>
              )}
            </div>
          </div>
          <div className="mt-2">
            <FormGroup
              inputLabel={"Email:"}
              placeholder={"Email"}
              name={"email"}
              value={formik.values.email}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            />
            {formik.errors.email && (
              <p className="text-pink-600 text-sm mt-1">
                {formik.errors.email}
              </p>
            )}
          </div>
          <label htmlFor="message">Message:</label>
          <textarea
            cols={4}
            rows={4}
            placeholder="Message"
            name="message"
            className="rounded-md px-2 py-3 shadow-sm  text-black"
            value={formik.values.message}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
          />
          {formik.errors.message && (
            <p className="text-pink-600 text-sm mt-1">
              {formik.errors.message}
            </p>
          )}

          <button
            disabled={loading}
            type="submit"
            className="px-3 py-2 bg-green-500 rounded-lg shadow-sm mt-2 hover:bg-green-600"
          >
            {loading ? "Submitting..." : "Submit"}
          </button>
        </form>
      )}
    </div>
  );
};

export default Contact;

服务器组件:

import Contact from "@/app/(models)/Contact";
import { NextResponse } from "next/server";

export async function POST(req) {
  const { firstName, lastName, email, message } = await req.body;

  try {
    const newContact = await Contact.create({
      firstName,
      lastName,
      email,
      message,
    });

    if (newContact) {
      return NextResponse.json(
        {
          message:
            "Successfully recieved your message. We will respond to you shortly!",
        },
        { status: 201 }
      );
    }
  } catch (error) {
    return NextResponse.json({ message: "Error!", error }, { status: 500 });
  }
}
javascript next.js server-side-rendering formik yup
1个回答
0
投票

req.body
ReadableStream
,请使用
await req.json()
代替
await req.body

参考:https://github.com/vercel/next.js/discussions/46483

© www.soinside.com 2019 - 2024. All rights reserved.