Pass a hidden input value with stateful React form

Site: https://brdchallenge.netlify.app/

I have built a quiz app in React which gives you a score and asks you to submit a form at the end. I have passed the score into an input text value using props and setState. The score shows up on the form in my app, but is not getting passed to netlify.

I am adding the score to my Form component like this (edited for clarity):

        constructor(props) {
            super(props);
            this.state = {
              fullname: '',  
              savedScore: this.props.saveScore
            };
            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
          }

      handleChange = e => {
        this.setState({
          [e.target.name]: e.target.value
        });
      };

      handleSubmit = e => {
        const form = e.currentTarget;
     
        if (form.checkValidity() === true ) {
          this.setState({
            savedScore: this.props.saveScore
          })
          fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: encode({ "form-name": "contact", ...this.state })
          })
            .catch(error => alert(error));

        }
        e.preventDefault();
      };
    render() {
    return (
    <form onSubmit={this.handleSubmit}>
        <input type="hidden" name="form-name" value="contact" />
       <input type="text" name="fullname" placeholder="Full name*" value={this.state.fullname} onChange={this.handleChange} />
        <input type="text" id="score" name="score" value={this.state.savedScore}></input>
    </form>
    )
    };

And I have a static html form:

<form name="contact" netlify netlify-honeypot="bot-field" hidden>
            <input type="text" name="fullname" />
            <input type="text" name="score" />
          </form>

All my other fields show up except for this one. Any ideas?

Hey @bwickerson,
A few things you could check:

  • can you log or display the form before you submit it, either with console.log or render it in an alert so you know it has the values you expect? That will help us narrow the scope of the problem- if the score value is blank there, then it makes sense that that’s what’s being sent.
  • have you tried without the static html form? Here’s some sample code that’s doing something similar, with the whole form in the render() section (there is a different form encoding function, but yours seems to be working so no need to change that part): Add form component with routing to custom success page · kaganjd/gatsby-starter-default-form@f8a374c · GitHub

Let us know how it goes!

Thanks Jen!
I have tried rendering an alert, just after the form is sent and I was able to retain the data.

fetch("/", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: encode({ "form-name": "contact", ...this.state })
      })
         .then(() => {
           alert('SUCCESS ' + this.state.fullname + ' scored ' + this.state.savedScore);
         })
        .catch(error => alert(error));

So definitely still stumped about what point the data is lost, because the alert shows after the form is submitted, and I can see the value is there in the input field before hitting submit.

However, I have not tried it without the static form, I thought it was necessary. I will check out that sample and report back!

Hi @jen,

I replaced my form with the one from the sample code and I commented out my static form and I get no results in Netlify. I also had a lot of trouble setting up the form initially, I have never been able to get any submission results in Netlify without the static form.

Here’s the code I used:

import React, { useState } from "react"

const NameForm = (props) => {
  const [name, setName] = useState("");
  //const [score, setScore] = useState("");

  // This function puts all the form fields into a FormData constructor, which we later encode with the URLSearchParams constructor
  const createFormDataObj = (data) => {
    const formData = new FormData();
    Object.keys(data).forEach((k) => {
      formData.append(k, data[k])
    });
    return formData
  }

  const handleSubmit = (e) => {
    // This `data` object is what's passed to the createFormDataObj. It needs all of your form fields, where the key is the name= attribute and the value is the value=
    const data = {
      "form-name": "testform",
      "name": name
    }
    // This POSTs your encoded form to Netlify with the required headers (for text; headers will be different for POSTing a file) and, on success, redirects to the custom success page using Gatsby's `navigate` helper function that we imported at the top
    fetch("/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams(createFormDataObj(data)).toString()
    })
      .catch(error => alert(error));
    // This is required to prevent the default onSubmit behavior
    e.preventDefault();
  };

  return (
    <form netlify action="/" name="testform" method="post" onSubmit={handleSubmit}>
      <label>
        First Name:
        <input
          name="firstName"
          type="text"
          value={name}
          onChange={e => setName(e.target.value)}
        />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

export default NameForm

Sorry to hear that that didn’t work for you.

I just tested your form again and have one more thought! Let’s go back to having the static form. You said your form looks like this:

<form name="contact" netlify netlify-honeypot="bot-field" hidden>
            <input type="text" name="fullname" />
            <input type="text" name="score" />
</form>

But the POST request to us sends:

savedScore	"1000"

Maybe the “score” attribute in your submissions are empty since there’s no data associated with that key. Could you try changing the name of that input to “savedScore”?

1 Like

OMG that worked. I can’t believe it was so simple. Unbelievable…, but also typical. LOL

Thank you sooooo much!

YAY! So glad to hear :tada:

1 Like