web-dev-qa-db-fra.com

Obtenir les données de formulaire dans Reactjs

J'ai un formulaire simple dans ma fonction render, comme ceci:

render : function() {
      return (
        <form>
          <input type="text" name="email" placeholder="Email" />
          <input type="password" name="password" placeholder="Password" />
          <button type="button" onClick={this.handleLogin}>Login</button>
        </form>
      );
    },
handleLogin: function() {
   //How to access email and password here ?
}

Que dois-je écrire dans ma handleLogin: function() { ... } pour accéder aux champs Email et Password?

127
myusuf

Utilisez les événements change sur les entrées pour mettre à jour l'état du composant et y accéder dans handleLogin:

handleEmailChange: function(e) {
   this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
   this.setState({password: e.target.value});
},
render : function() {
      return (
        <form>
          <input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
          <input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
          <button type="button" onClick={this.handleLogin}>Login</button>
        </form>);
},
handleLogin: function() {
    console.log("EMail: " + this.state.email);
    console.log("Password: " + this.state.password);
}

Le violon en marche: http://jsfiddle.net/kTu3a/

En outre, lisez la documentation, une section entière est dédiée à la gestion des formulaires: http://facebook.github.io/react/docs/forms.html

Auparavant, vous pouviez également utiliser le mixin d'aide à la liaison de données bidirectionnel de React pour obtenir le même résultat, mais il est maintenant déconseillé au lieu de définir le gestionnaire de valeur et de modification (comme ci-dessus):

var ExampleForm = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {email: '', password: ''};
  },
  handleLogin: function() {
    console.log("EMail: " + this.state.email);
    console.log("Password: " + this.state.password);
  },
  render: function() {
    return (
      <form>
        <input type="text" valueLink={this.linkState('email')} />
        <input type="password" valueLink={this.linkState('password')} />
        <button type="button" onClick={this.handleLogin}>Login</button>
      </form>
    );
  }
});

La documentation est ici: http://facebook.github.io/react/docs/two-way-binding-helpers.html

123
jbaiter

Il y a quelques façons de le faire:

1) Obtenir les valeurs d'un tableau d'éléments de formulaire par index

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target[0].value)
}

2) Utilisation de l'attribut name en HTML

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target.elements.username.value) // from elements property
  console.log(event.target.username.value)          // or directly
}

<input type="text" name="username"/>

3) Utilisation des références

handleSubmit = (event) => {
  console.log(this.inputNode.value)
}

<input type="text" name="username" ref={node => (this.inputNode = node)}/>

Exemple complet

class NameForm extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault()
    console.log(event.target[0].value)
    console.log(event.target.elements.username.value)
    console.log(event.target.username.value)
    console.log(this.inputNode.value)
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input
            type="text"
            name="username"
            ref={node => (this.inputNode = node)}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    )
  }
}
64

Une autre approche consiste à utiliser l'attribut ref et à référencer les valeurs avec this.refs. Voici un exemple simple:

render: function() {
    return (<form onSubmit={this.submitForm}>
        <input ref="theInput" />
    </form>);
},
submitForm: function(e) {
    e.preventDefault();
    alert(React.findDOMNode(this.refs.theInput).value);
}

Plus d'informations peuvent être trouvées dans les documents React: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute

Pour beaucoup des raisons décrites dans Comment utiliser les boutons radio dans React? }, Cette approche n'est pas toujours la meilleure, mais elle constitue une alternative utile dans certains cas simples.

41
Jamund Ferguson

Un moyen facile de traiter avec les arbitres: 

class UserInfo extends React.Component {

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

  handleSubmit(e) {
    e.preventDefault();
    
    const formData = {};
    for (const field in this.refs) {
      formData[field] = this.refs[field].value;
    }
    console.log('-->', formData);
  }

  render() {
    return (
        <div>
          <form onSubmit={this.handleSubmit}>
            <input ref="phone" className="phone" type='tel' name="phone"/>
            <input ref="email" className="email" type='tel' name="email"/>
            <input type="submit" value="Submit"/>
          </form>
        </div>
    );
  }
}

export default UserInfo;

16
E. Fortes

Je suggérerais l'approche suivante:

import {Autobind} from 'es-decorators';

export class Form extends Component {

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

    @Autobind
    add(e) {
        e.preventDefault();
        this.collection.add(this.state);
        this.refs.form.reset();
    }

    shouldComponentUpdate() {
        return false;
    }

    render() {
        return (
            <form onSubmit={this.add} ref="form">
                <input type="text" name="desination" onChange={this.handleChange}/>
                <input type="date" name="startDate" onChange={this.handleChange}/>
                <input type="date" name="endDate" onChange={this.handleChange}/>
                <textarea name="description" onChange={this.handleChange}/>
                <button type="submit">Add</button>
            </form>
        )
    }

}
9
James Akwuh

Vous pouvez remplacer le gestionnaire d'événements onClick du bouton par un gestionnaire onSubmit du formulaire:

render : function() {
      return (
        <form onSubmit={this.handleLogin}>
          <input type="text" name="email" placeholder="Email" />
          <input type="password" name="password" placeholder="Password" />
          <button type="submit">Login</button>
        </form>
      );
    },

Ensuite, vous pouvez utiliser FormData pour analyser le formulaire (et construire un objet JSON à partir de ses entrées si vous le souhaitez).

handleLogin: function(e) {
   const formData = new FormData(e.target)
   const user = {}

   e.preventDefault()

   for (let entry of formData.entries()) {
       user[entry[0]] = entry[1]
   }

   // Do what you will with the user object here
}
8
Michael

Si toutes vos entrées/zones de texte ont un nom, vous pouvez alors tout filtrer à partir de event.target:

onSubmit(event){
  const fields = Array.prototype.slice.call(event.target)
      .filter(el => el.name)
      .reduce((form, el) => ({
        ...form,
        [el.name]: el.value,
      }), {})
}

Forme totalement incontrôlable ???? sans méthodes onChange, value, defaultValue ...

6
Aral Roca

Donnez vos entrées ref comme ceci

<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />

alors vous pouvez y accéder dans votre handleLogin comme soo

handleLogin: function(e) {
   e.preventDefault();
    console.log(this.refs.email.value)
    console.log(this.refs.password.value)
}
4
Imran Rafique

Si vous utilisez Redux dans votre projet, vous pouvez envisager d'utiliser ce composant d'ordre supérieur https://github.com/erikras/redux-form .

3
ivks
 onChange(event){
     console.log(event.target.value);
  }
  handleSubmit(event){ 
    event.preventDefault();
    const formData = {};
      for (const data in this.refs) {
        formData[data] = this.refs[data].value;
      }
    console.log(formData);
  }



 <form onSubmit={this.handleSubmit.bind(this)}>
  <input type="text" ref="username" onChange={this.onChange} className="form-control"/>
  <input type="text" ref="password" onChange={this.onChange} className="form-control"/>
  <button type="submit" className="btn-danger btn-sm">Search</button>
 </form>

Image de sortie jointe ici

3
Milan Panigrahi

Dans de nombreux événements en javascript, nous avons event qui donne un objet, y compris ce qui s'est passé et quelles sont les valeurs, etc ...

C’est ce que nous utilisons également avec les formulaires dans ReactJs ...

Donc, dans votre code, vous définissez l'état sur la nouvelle valeur ... quelque chose comme ceci:

class UserInfo extends React.Component {

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

  handleLogin(e) {
    e.preventDefault();
    for (const field in this.refs) {
      this.setState({this.refs[field]: this.refs[field].value});
    }
  }

  render() {
    return (
        <div>
          <form onSubmit={this.handleLogin}>
            <input ref="email" type="text" name="email" placeholder="Email" />
            <input ref="password" type="password" name="password" placeholder="Password" />
            <button type="button">Login</button>
          </form>
        </div>
    );
  }
}

export default UserInfo;

C'est également l'exemple de formulaire dans React v.16, à titre de référence pour le formulaire que vous allez créer à l'avenir:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
3
Alireza

En outre, cela peut être utilisé aussi. 

handleChange: function(state,e) {
  this.setState({[state]: e.target.value});
},
render : function() {
  return (
    <form>
      <input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
      <input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
      <button type="button" onClick={this.handleLogin}>Login</button>
    </form>
  );
},
handleLogin: function() {
  console.log("EMail: ", this.state.email);
  console.log("Password: ", this.state.password);
}
2
Yurii Kosygin

Cela pourrait aider les utilisateurs de Meteor (v1.3):

render: function() {
    return (
        <form onSubmit={this.submitForm.bind(this)}>
            <input type="text" ref="email" placeholder="Email" />
            <input type="password" ref="password" placeholder="Password" />
            <button type="submit">Login</button>
        </form>
    );
},
submitForm: function(e) {
    e.preventDefault();
    console.log( this.refs.email.value );
    console.log( this.refs.password.value );
}
1
Joe L.

Exemple plus clair avec es6 destructing

class Form extends Component {
    constructor(props) {
        super(props);
        this.state = {
            login: null,
            password: null,
            email: null
        }
    }

    onChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    onSubmit(e) {
        e.preventDefault();
        let login = this.state.login;
        let password = this.state.password;
        // etc
    }

    render() {
        return (
            <form onSubmit={this.onSubmit.bind(this)}>
                <input type="text" name="login" onChange={this.onChange.bind(this)} />
                <input type="password" name="password" onChange={this.onChange.bind(this)} />
                <input type="email" name="email" onChange={this.onChange.bind(this)} />
                <button type="submit">Sign Up</button>
            </form>
        );
    }
}
1
Sergio Ivanuzzo

Ajoutant à la réponse de Michael Schock:

class MyForm extends React.Component {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    const data = new FormData(event.target);

    console.log(data.get('email')); // reference by form input's `name` tag

    fetch('/api/form-submit-url', {
      method: 'POST',
      body: data,
    });
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label htmlFor="username">Enter username</label>
        <input id="username" name="username" type="text" />

        <label htmlFor="email">Enter your email</label>
        <input id="email" name="email" type="email" />

        <label htmlFor="birthdate">Enter your birth date</label>
        <input id="birthdate" name="birthdate" type="text" />

        <button>Send data!</button>
      </form>
    );
  }
}

Voir cet article de taille moyenne: comment gérer les formulaires avec Just React

Cette méthode obtient les données de formulaire uniquement lorsque le bouton Soumettre est activé. Beaucoup plus propre IMO!

0
hoohoo-b

Si vous avez plusieurs occurrences d'un nom d'élément, vous devez utiliser forEach (). 

html

  <input type="checkbox" name="delete" id="flizzit" />
  <input type="checkbox" name="delete" id="floo" />
  <input type="checkbox" name="delete" id="flum" />
  <input type="submit" value="Save"  onClick={evt => saveAction(evt)}></input>

js

const submitAction = (evt) => {
  evt.preventDefault();
  const dels = evt.target.parentElement.delete;
  const deleted = [];
  dels.forEach((d) => { if (d.checked) deleted.Push(d.id); });
  window.alert(deleted.length);
};

Notez que dels dans ce cas est un RadioNodeList, pas un tableau, et n'est pas un Iterable ForEach () est une méthode intégrée de la classe list. Vous ne pourrez pas utiliser une carte () ou réduire () ici.

0
Jeff Lowery

Améliorer l'expérience utilisateur; Lorsque l'utilisateur clique sur le bouton d'envoi, vous pouvez essayer d'obtenir le formulaire pour afficher d'abord un message d'envoi. Une fois que nous avons reçu une réponse du serveur, celui-ci peut mettre à jour le message en conséquence. Nous y parvenons dans React en chaînant les statuts. Voir codepen ou des extraits ci-dessous:

La méthode suivante effectue le premier changement d'état:

handleSubmit(e) {
    e.preventDefault();
    this.setState({ message: 'Sending...' }, this.sendFormData);
}

Dès que React affiche le message Envoi ci-dessus à l'écran, il appelle la méthode qui enverra les données du formulaire au serveur: this.sendFormData (). Pour plus de simplicité, j'ai ajouté un setTimeout pour imiter cela.

sendFormData() {
  var formData = {
      Title: this.refs.Title.value,
      Author: this.refs.Author.value,
      Genre: this.refs.Genre.value,
      YearReleased: this.refs.YearReleased.value};
  setTimeout(() => { 
    console.log(formData);
    this.setState({ message: 'data sent!' });
  }, 3000);
}

Dans React, la méthode this.setState () restitue un composant avec de nouvelles propriétés. Ainsi, vous pouvez également ajouter une certaine logique à la méthode render () du composant de formulaire, qui se comportera différemment en fonction du type de réponse obtenu du serveur. Par exemple:

render() {
  if (this.state.responseType) {
      var classString = 'alert alert-' + this.state.type;
      var status = <div id="status" className={classString} ref="status">
                     {this.state.message}
                   </div>;
  }
return ( ...

codepen

0
Homam Bahrani

J'utilise comme ceci en utilisant l'état de React Component:

<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />

handleChange(e){
   this.setState({[e.target.name]: e.target.value})
}`
0
Adnan Boota