我有一个表单组件,可以在网站上重复使用,该组件将表单名称作为参数。该网站是使用Gatsby构建的,并托管在Netlify上。
每当我尝试填写表单并按Submit按钮时,控制台中都会出现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"
/>
关于我在做什么错的任何想法?
答案 0 :(得分:0)
结果证明,我不能像以前那样传递数据,Chrome开发人员工具将表单名称显示为[Object,object],而不是我在console.logging时输入的名称。为了解决这个问题,我对名称进行了字符串化。
此行解决了我的问题:
const formName = JSON.stringify(name);
然后以我的形式将值作为普通变量传递
<input type="hidden" name="form-name" value={formName} />
编辑:此方法有一个主要缺陷,所有名称现在都用引号引起来。如果有更好的方法,请发布。
答案 1 :(得分: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;