1

我有一个可以在网站上重复使用的表单组件,该组件将表单名称作为参数。该站点使用 Gatsby 构建并托管在 Netlify 上。

每当我尝试填写表单并按下提交按钮时,我的控制台中都会出现 404 错误并且表单未提交,但我可以在 Netlify Forms 中看到所有表单。我不确定我的错误在哪里,当我在 chrome 中检查时,我发现该data-netlify="true"属性不存在于我的前端,但它存在于代码中。

我的职能

import React, { useState } from "react"
import { useForm } from "react-hook-form"

function encode(data) {
  return Object.keys(data)
    .map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
    .join("&")
}

const ContactForm = ({ data, name, type, index }) => {
  const { register, handleSubmit, errors, reset } = useForm({
    mode: "onBlur",

  })

  const [feedbackState, setFeedbackState] = useState(null)
  const [errorState, setErrorState] = useState(null)
  const [requestType, setRequestType] = useState(null)
  const [state, setState] = useState({})

  const handleChange = (e) => {
    {
      setState({ ...state, [e.target.name]: e.target.value })
    }
  }
  const onSubmit = (data, e) => {
    e.preventDefault()
    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({
        "form-name": {name},
        ...state,
      }),
    })
      .then((response) => {
        setFeedbackState(true)
        reset()
      })
      .catch((error) => {
        setErrorState(true)
      })
  }

我的表格:

if (feedbackState) {
    return (
      <div className="callout success">
        <h3>Vad roligt att du är intresserad av våra produkter!</h3>
        <p>
          Vi kommer höra av oss inom kort till {state.fName} {state.lName} på{" "}
          {state.email}.
        </p>
      </div>
    )
  } else {
    return (
      <>
        {console.log("form navn er, ", name)}
        <form
          id="contactMe"
          onSubmit={handleSubmit(onSubmit)}
          name={name}
          method="post"
          data-netlify="true"
          data-netlify-honeypot="bot-field"
        >
          <input type="hidden" name="form-name" value={name} />
          <div hidden>
            <label>
              Don’t fill this out:{' '}
              <input name="bot-field" onChange={handleChange} />
            </label>
          </div>          <fieldset class="grid-x grid-margin-x">
            <legend class="cell">
              <h3>{data.formTitle}</h3>
            </legend>

            <div class="cell medium-6">
              <div class="form-field">
                <label htmlFor="fName">
                  {data.firstName}
                  <span
                    id="error-required-field"
                    style={{
                      display:
                        errors.fName && errors.fName.type === "required"
                          ? "block"
                          : "none",
                    }}
                  >
                    {data.firstNameRequired}
                  </span>
                  <span style={{ display: "none" }}>
                    <label>Request type: </label>
                    <input
                      type="text"
                      id="requestType"
                      onChange={handleChange}
                      name="requestType"
                      value={type}
                      ref={register({ required: true })}
                    />
                  </span>
                </label> ....more form values

可以在这里看到我如何查看表单的示例,我已经尝试使用 console.logging 我的表单中的所有属性,并且可以看到所有这些属性

<ContactForm
    name="Tilgjenlighetsanalys"
    data={data.auditsForm}
    type="Liten analys"
  />

关于我做错了什么的任何想法?

编辑:当我提交表单名称设置为 [object Object] 而不是实际表单名称时,我可以在我的 chrome 网络选项卡中看到 屏幕截图 ov chrome 开发工具网络选项卡将表单名称显示为对象对象

4

2 回答 2

0

只是想补充一点,必须在将应用程序部署到 netlify 后完成对表单的测试。在本地测试会给你一个 404

如果您部署并仍然出现错误,请删除验证码(如果您保留验证码并且验证码设置不正确,您将收到 303 错误 - 我建议删除验证码以确保您的表单正常工作,然后您可以攻击验证码问题,因为他们有很多关于如何正确添加它的文章 - 下面是我在生产中的工作 gatsby/netlify 表单

import React, { useState } from 'react';
import styled from 'styled-components';
import { navigate } from 'gatsby';
import SEO from '../components/SEO';

const StyledContactPage = styled.section`
  display: grid;
  place-items: center;
  min-height: calc(100vh - 12rem);
  article {
    background: var(--clr-concrete-white);
    border-radius: var(--radius);
    text-align: center;
    box-shadow: var(--light-shadow);
    transition: var(--transition);
    width: 90vw;
    max-width: 35rem;
    &:hover {
      box-shadow: var(--dark-shadow);
    }
    h3 {
      padding-top: 1.25rem;
      color: var(--clr-primary);
    }
    .form-group {
      padding: 1rem 1.5rem;
    }
    .form-control {
      display: block;
      width: 100%;
      padding: 0.75rem 1rem;
      border: none;
      margin-bottom: 1.25rem;
      background: var(clr-codgray-black);
      /* background: red; */
      border-radius: var(--radius);
      text-transform: uppercase;
      letter-spacing: var(--spacing);
      &::placeholder {
        font-family: var(--ff-primary);
        color: var(--clr-jewel-green);
        text-transform: uppercase;
        letter-spacing: var(--spacing);
      }
    }
    .submit-btn {
      display: block;
      width: 100%;
      padding: 1rem;
      border-bottom-left-radius: var(--radius);
      border-bottom-right-radius: var(--radius);
      border-top-right-radius: 0;
      border-top-left-radius: 0;
    }
  }
`;

const ContactPage = () => {
  const [formState, setFormState] = useState({
    firstName: '',
    lastName: '',
    jobTitle: '',
    companyName: '',
    phone: '',
    email: '',
    message: '',
  });

  // encodes the captured form data in the format that Netlify's backend requires
  // example: form-name=contact&firstName=a&lastName=b&jobTitle=a&companyName=a&phone=3&email=me%40you.com&message=tes
  const encode = (data) => {
    return Object.keys(data)
      .map(
        (key) => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])
      )
      .join('&');
  };

  const handleChange = (event) => {
    setFormState({
      ...formState,
      [event.target.name]: event.target.value,
    });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    const form = event.target;
    fetch('/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: encode({
        'form-name': form.getAttribute('name'),
        ...formState,
      }),
    })
      .then(() => navigate(form.getAttribute('action')))
      .catch((error) => alert(error));
  };

  return (
    <>
      <SEO title="Contact" />
      <StyledContactPage className="page">
        <article>
          <h3>get in touch</h3>
          <p>
            For a more indepth look at our protection services and rates call us
            at 1-800-Get-Safe or fill out the form below! A representative will
            be in touch shortly.
          </p>
          <form
            name="contact"
            method="POST"
            data-netlify="true"
            data-netlify-honeypot="bot-field"
            action="/thank-you"
            onSubmit={handleSubmit}
          >
            <input type="hidden" name="form-name" value="contact" />
            <div className="form-group">
              <label htmlFor="first-name" className="sr-only">
                First Name
              </label>
              <input
                id="first-name"
                name="firstName"
                type="text"
                placeholder="First Name"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.firstName}
              />
              <label htmlFor="last-name" className="sr-only">
                Last Name
              </label>
              <input
                id="last-name"
                name="lastName"
                type="text"
                placeholder="Last Name"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.lastName}
              />
              <label htmlFor="job-title" className="sr-only">
                Job Title
              </label>
              <input
                id="job-title"
                name="jobTitle"
                type="text"
                placeholder="Job Title"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.jobTitle}
              />
              <label htmlFor="company-name" className="sr-only">
                Company Name
              </label>
              <input
                id="company-name"
                name="companyName"
                type="text"
                placeholder="Company Name"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.companyName}
              />
              <label htmlFor="phone" className="sr-only">
                Phone
              </label>
              <input
                id="phone"
                name="phone"
                type="number"
                placeholder="Phone Number"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.phone}
              />
              <label htmlFor="email" className="sr-only">
                Phone
              </label>
              <input
                name="email"
                type="email"
                placeholder="email"
                className="form-control"
                onChange={handleChange}
                value={formState.email}
              />
              <label htmlFor="message" className="sr-only">
                How can we help you?
              </label>
              <textarea
                id="message"
                name="message"
                rows="5"
                placeholder="message"
                className="form-control"
                required
                onChange={handleChange}
                value={formState.message}
              ></textarea>
            </div>
            <button type="submit" className="submit-btn btn">
              submit here
            </button>
          </form>
        </article>
      </StyledContactPage>
      {/* </div> */}
      {/* /.page */}
    </>
  );
};

export default ContactPage;
于 2020-11-28T03:01:19.033 回答
0

事实证明,我不能像以前那样传递数据,Chrome 开发工具将表单名称显示为 [Object, object],而不是我在 console.logged 传递的名称值时得到的名称。为了解决这个问题,我对名称进行了字符串化。

这一行解决了我的问题:

  const formName = JSON.stringify(name);

然后在我的表单中,我将值作为普通变量传递

  <input type="hidden" name="form-name" value={formName} />

编辑:此方法有一个重大缺陷,所有名称现在都用引号传递。如果有人有更好的方法,请发布。

于 2020-04-17T13:09:20.020 回答