Steffi
Steffi

Reputation: 7077

How to send input hidden in React JS?

I have this form, and I would like to send these values. I know we have to use setState() to store data but how does it work for input type="hidden"?

  1. First question: How to store input hidden to setState ?
  2. Second question: How to serialize data like form.serialize() ?
  3. Third question: How to send these serialize values? Ajax or Axios, who is the better?

Here is the code:

handleSubmit(e) {
    e.preventDefault();

   /**
    $.ajax({
        url: "post.php",
        type: "POST",
        data: DATA,
        success:function(data) {

        }
    });
    **/
 }

            <form onSubmit={this.handleSubmit}>
                        <input type="hidden" name="action" value="login" />
                        <input type="email" name="email_user" placeholder="Email" />
                        <input type="password" name="password_user" placeholder="Mot de passe" />
                        <button type="submit">Login</button>
            </form>

Upvotes: 8

Views: 65402

Answers (3)

Abraham
Abraham

Reputation: 9885

All data can be stored on React's state, but if you still need to have inputs on your form you can do something like this:

const handleSubmit = e => {
     e.preventDefault();
     const inputs = Object.values(e.target)
        .filter(c => typeof c.tagName === 'string' && c.tagName.toLowerCase() === 'input')
        .reduce((acc, curr) => ({ ...acc, [curr.name]: curr.value }), {});

     setFormVals({ ...formVals, ...inputs });
}

See the demo below:

const Demo = () => {
    const [formValues] = React.useState({});

    const handleSubmit = e => {
        e.preventDefault();
        const inputs = Object.values(e.target)
            .filter(c => typeof c.tagName === 'string' && c.tagName.toLowerCase() === 'input')
            .reduce((acc, curr) => ({ ...acc, [curr.name]: curr.value }), {});

        console.log(inputs);
    }

    return (
        <form onSubmit={handleSubmit}>
            <input name="name" placeholder="Name" value={formValues.name} />
            <input name="email" placeholder="Email" value={formValues.email} />
            <input name="hiddenInput" value="hiddenValue" type="hidden" />
            <button type="submit">Submit</button>
        </form>
    );
}

ReactDOM.render(<Demo />, document.getElementById('demo'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

<div id="demo"></div>

If you know what the inputs that you need you can do something like this:

const Demo = () => {
    const formRef = React.useRef(null);
    const [formValues, setFormValues] = React.useState({});
    
    const handleChange = e => {
      setFormValues({
        ...formValues,
        [e.target.name]: e.target.value,
      });
    }
    
    const handleSubmit = e => {
      e.preventDefault();
      setFormValues({ ...formValues, hiddenInput: formRef.current.hiddenInput.value });
    }
    
    return (
        <form onSubmit={handleSubmit} ref={formRef}>
            <input name="name" placeholder="Name" value={formValues.name} onChange={handleChange} />
            <input name="email" placeholder="Email" value={formValues.email} onChange={handleChange} />
            <input name="hiddenInput" value="hiddenValue" type="hidden" />
            <button type="submit">Submit</button>
            <pre>{JSON.stringify(formValues, null, 2)}</pre>
        </form>
    );
}

ReactDOM.render(<Demo />, document.getElementById('demo'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

<div id="demo"></div>

Upvotes: 3

ShabashP
ShabashP

Reputation: 578

The answer is complex for all your questions.

First of all, it depends on the task: if you just want to send asynchonous request to server on form submit, you don't need to use Component state. Here is a link to the relevant section of the documentation. And use refs to access inputs data.

class FormComponent extends React.Component {

    constructor(props) {
        super(props);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onSubmit(e) {
        e.preventDefault();

        // Send your ajax query via jQuery or Axios (I prefer Axios)
        axios.get('your_url', {
            params: {
              action: this.actionInput.value,
              email: this.emailInput.value,
              password: this.passwordInput.value,
            }
          })
          .then(function (response) {
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });

    }

    render() {
        return (
            <form onSubmit={this.onSubmit}>
                <input type="hidden" name="action" value="login" 
                       ref={(input) => { this.actionInput = input }} />

                <input type="email" name="email_user" placeholder="Email" 
                       ref={(input) => { this.emailInput = input }}/>

                <input type="password" name="password_user" placeholder="Mot de passe" 
                       ref={(input) => { this.passwordInput = input }}/>

                <button type="submit">Login</button>
            </form>
        );
    }
}

Upvotes: 5

vorillaz
vorillaz

Reputation: 6286

Answering your questions:

  1. Since you know how to use component's state you may set the value as : <input type='text' value={this.state.foo} /> or even via props passing <input type='hidden' value={this.props.foo} />

  2. You don't need to serialise anything at all. Use your component's local state or even a state container like Redux or Flux in order to pick the appropriate data. Take a look at this fairly simple example:

    var SuperForm = React.createClass({
    getInitialState() {
      return { 
        name: 'foo', 
        email: '[email protected]'
      };
    },
    
    submit(e){
      e.preventDefault();
      console.log("send via AJAX", this.state)
    },
    
    change(e,key){
      const newState = {};
      newState[key] = e.currentTarget.value;
      this.setState(newState)
    },
    
    render: function() {
        return (
        <div>
          <label>Name</label>
          <input 
            onChange={(e) => this.change(e,'name')}
            type="text" 
            value={this.state.name} />
          <label>Email</label>  
          <input 
            onChange={(e) => this.change(e,'email')}
            type="text" 
            value={this.state.email} />
          <button onClick={this.submit}>Submit</button>
        </div>
      );
    }});
    

    Demo

  3. AJAX is a set of web development techniques while Axios is a JavaScript framework. You may use jQuery, Axios or even vanilla JavaScript.

Upvotes: 0

Related Questions