首页 > 解决方案 > Gatsby 仅将复选框值传递给 Netlify 表单

问题描述

我有一组复选框,我想将已选择的复选框传递给 Netlify 表单。

现在只传递了一个值,而不是我希望它们都被传递并很好地格式化(中间有一个逗号)。

我的复选框看起来像这样,它遍历从无头 CMS 的数组中获取的数据,并按应有的方式显示所有复选框

 <fieldset>
    <legend>Inquery type</legend>
    {formData.radioButtons.map((node, index) => (
      <>
        <p>
          <label key={index}>
            <input
              type="checkbox"
              id={("inqueryType", index)}
              name="inqueryType"
              ref={register()}
              value={node}
              onChange={handleChange}
              key={(node, "checbox")}
            />
            {node}
          </label>
        </p>
      </>
    ))}
  </fieldset>

我的 handleChange 函数看起来像这样

  const handleChange = e => {
    if (e.target.type === "checkbox" && !e.target.checked) {
      setState(prev => ({ ...prev, [e.target.name]: e.target.value }))
    } else {
      setState({ ...state, [e.target.name]: e.target.value })
    }
  }

我怀疑我的错误出在我的 handleChange 方法中,但我一直无法弄清楚为什么它只存储一个值而不是所有值。有任何想法吗?

我的 onSubmit 看起来像这样

const onSubmit = (data, e) => {
    e.preventDefault()
    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({
        "form-name": "contactGudcForm",
        ...state,
      }),
    })
      .then(response => {
        setFeedbackMsg(`Thanks for reaching out. I'll get back to you soon.`)
        reset()
        console.log(response)
      })
      .catch(error => {
        setFeedbackMsg(
          "Oops, something went wrong. The form could not be submitted."
        )
        console.log(error)
      })
  }

我的 encude 函数,从 StackOverflow 中无耻地偷来,看起来像这样

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

这是一个使用标准 Netlify 表单部署到 Netlify 的 Gatsby 项目

标签: javascriptreactjsgatsby

解决方案


The issue is that your checkboxes share the same name attribute (inqueryType in your example), therefore they will overwrite eachother here:

const handleChange = e => {
  // ...
  setState(prev => ({ ...prev, [e.target.name]: e.target.value }))
  // ...
}

What happens is that you're adding the form data to state using the inputs' name as the key. Since your checkboxes don't have a unique name, it kind of does this:

const state = {}

// push the value of the first checkbox
state["inqueryType"] = "value 1"

// push the value of the second checkbox
state["inqueryType"] = "value 2"

// "value 1" is gone :(

Make sure that your keys are unique, and you should be fine!

Edit: as mentioned in the comments, you can format the data in any shape you like, as long as you don't overwrite it. If you want a stringified array of values for your group of checkboxes, you could do something like this:

const handleChange = e => {
  if (e.target.name === "inqueryType") {
    const inqueryType = [...state.inqueryType, e.target.value]
    setState({ ...state, inqueryType: JSON.stringify(inqueryType) })
  }
  else {
    setState({ ...state, [e.target.name]: e.target.value })
  }
}

Of course there might be better solutions for your particular use case - this part is up to you :)


推荐阅读