pour appeler l'événement onChange après avoir appuyé sur la touche Entrée

204

Je suis nouveau sur Bootstrap et coincé avec ce problème. J'ai un champ de saisie et dès que j'entre un seul chiffre, la fonction de onChangeest appelée, mais je veux qu'elle soit appelée lorsque j'appuie sur «Entrée» lorsque le numéro entier a été entré. Le même problème pour la fonction de validation - elle appelle trop tôt.

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
  //bsStyle: this.validationInputFactor(),
  placeholder: this.initialFactor,
  className: "input-block-level",
  onChange: this.handleInput,
  block: true,
  addonBefore: '%',
  ref:'input',
  hasFeedback: true
});
Bill Lumbert
la source

Réponses:

404

Selon React Doc , vous pouvez écouter les événements du clavier, comme onKeyPressou onKeyUpnon onChange.

var Input = React.createClass({
  render: function () {
    return <input type="text" onKeyDown={this._handleKeyDown} />;
  },
  _handleKeyDown: function(e) {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }
});

Mise à jour: utilisez React.Component

Voici le code utilisant React.Component qui fait la même chose

class Input extends React.Component {
  _handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }

  render() {
    return <input type="text" onKeyDown={this._handleKeyDown} />
  }
}

Voici le jsfiddle .

Mise à jour 2: utiliser un composant fonctionnel

const Input = () => {
  const handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      console.log('do validate')
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} />
}
wuct
la source
2
Et vous souhaitez également lier le processus de validation à l' onBlurévénement.
wuct
5
Même solution de manière plus compacte en référence au texte d'entrée:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind
5
@musemind En fait, vous n'avez pas besoin d'utiliser ref. <input onKeyPress={e => doSomething(e.target.value)}est suffisant.
wuct
4
@musemind Le point d'utiliser une méthode de classe au lieu d'une fonction en ligne est d'éviter de créer une nouvelle fonction à chaque fois qu'elle onKeyPressest déclenchée. C'est une amélioration subtile de la perf.
wuct
1
le violon attaché ne fonctionne plus, veuillez vérifier, de toute façon une belle réponse
Pardeep Jain
52

Vous pouvez utiliser onKeyPress directement sur le champ de saisie. La fonction onChange change la valeur d'état à chaque changement de champ de saisie et après avoir appuyé sur Entrée, elle appellera une recherche de fonction ().

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>
Admir
la source
cette réponse fonctionne pour moi plutôt que la réponse acceptée ci-dessus.
karthik shankar
Si vous avez une forme lourde, je recommanderais de créer une fonction en dehors de la méthode de rendu et de la passer comme référence, comme onKeyPress={this.yourFunc}sinon la fonction de la grosse flèche sera recréée sur chaque rendu.
Viktor
cela fonctionne pour le cas où l'événement onKeyPress est également écrit pour l'entrée et le cas parent. Merci.
Naveen Kumar PG
OuonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid
24

appuyer sur Entrée lorsque le focus sur un contrôle de formulaire (entrée) déclenche normalement un submitévénement (onSubmit) sur le formulaire lui-même (pas l'entrée) afin que vous puissiez lier votre this.handleInputformulaire au formulaire onSubmit.

Alternativement, vous pouvez le lier à l' blurévénement (onBlur) inputqui se produit lorsque le focus est supprimé (par exemple, tabulation vers l'élément suivant qui peut obtenir le focus)

Luca
la source
3
C'est beaucoup plus propre que l'utilisation onKeyPress.
Blackus
1
Pensé puisque la cible est différente, event.target.valuen'est pas disponible
Izkata
@Izkata ce que vous dites est absolument correct; ma réponse pourrait nécessiter une manière différente de gérer les choses dans la handleInputméthode du contrôleur . Faire selon ma réponse vous couvrirait à la fois lorsque l'utilisateur appuie sur Entrée tout en se concentrant sur l'entrée et lors de l'activation d'un submitbouton / entrée.
Luca
Dans la plupart des situations dans les applications Web, il n'y a pas de formulaires, juste des entrées, donc cette réponse n'est pas pertinente pour la majorité des cas d'utilisation, à
mon humble avis
@vsync, il pourrait ne pas être pertinent pour la majorité, mais toujours valable pour une partie - et certainement pas incorrect, je ne pense pas que cela vaille le coup
Luca
8

Vous pouvez utiliser event.key

function Input({onKeyPress}) {
  return (
    <div>
      <h2>Input</h2>
      <input type="text" onKeyPress={onKeyPress}/>
    </div>
  )
}

class Form extends React.Component {
  state = {value:""}

  handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      this.setState({value:e.target.value})
    }
  }

  render() {
    return (
      <section>
        <Input onKeyPress={this.handleKeyPress}/>
        <br/>
        <output>{this.state.value}</output>
      </section>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById("react")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

onmyway133
la source
5

Réagissez les utilisateurs, voici une réponse pour être complet.

React version 16.4.2

Vous souhaitez soit mettre à jour pour chaque frappe ou obtenir la valeur uniquement lors de la soumission. L'ajout des événements clés au composant fonctionne, mais il existe des alternatives comme recommandé dans les documents officiels.

Composants contrôlés vs composants non contrôlés

Contrôlé

À partir des documents - Formulaires et composants contrôlés :

En HTML, les éléments de formulaire tels que l'entrée, la zone de texte et la sélection conservent généralement leur propre état et le mettent à jour en fonction des entrées de l'utilisateur. Dans React, l'état mutable est généralement conservé dans la propriété state des composants et mis à jour uniquement avec setState ().

Nous pouvons combiner les deux en faisant de l'état React la «source unique de vérité». Ensuite, le composant React qui restitue un formulaire contrôle également ce qui se passe dans ce formulaire lors de la saisie par l'utilisateur. Un élément de formulaire d'entrée dont la valeur est ainsi contrôlée par React est appelé «composant contrôlé».

Si vous utilisez un composant contrôlé, vous devrez maintenir l'état à jour pour chaque modification de la valeur. Pour cela, vous liez un gestionnaire d'événements au composant. Dans les exemples des documents, généralement l'événement onChange.

Exemple:

1) Lier le gestionnaire d'événements dans le constructeur (valeur maintenue à l'état)

constructor(props) {
    super(props);
    this.state = {value: ''};

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

2) Créer une fonction de gestionnaire

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

3) Créer une fonction de soumission de formulaire (la valeur est tirée de l'état)

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

4) Rendre

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>

Si vous utilisez des composants contrôlés , votre handleChangefonction sera toujours déclenchée, afin de mettre à jour et de conserver le bon état. L'État aura toujours la valeur mise à jour et lorsque le formulaire sera soumis, la valeur sera prélevée sur l'État. Cela peut être un problème si votre fiche est très longue, car vous devrez créer une fonction pour chaque composant, ou en écrire une simple qui gère la modification de valeur de chaque composant.

Incontrôlé

À partir des documents - Composant non contrôlé

Dans la plupart des cas, nous vous recommandons d'utiliser des composants contrôlés pour implémenter des formulaires. Dans un composant contrôlé, les données de formulaire sont gérées par un composant React. L'alternative est les composants non contrôlés, où les données de formulaire sont gérées par le DOM lui-même.

Pour écrire un composant non contrôlé, au lieu d'écrire un gestionnaire d'événements pour chaque mise à jour d'état, vous pouvez utiliser une référence pour obtenir des valeurs de formulaire à partir du DOM.

La principale différence ici est que vous n'utilisez pas la onChangefonction, mais plutôt onSubmitle formulaire pour obtenir les valeurs et valider si nécessaire.

Exemple:

1) Lier le gestionnaire d'événements et créer une référence à l'entrée dans le constructeur (aucune valeur conservée dans l'état)

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

2) Créer une fonction d'envoi de formulaire (la valeur est tirée du composant DOM)

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

3) Rendre

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>

Si vous utilisez des composants non contrôlés , il n'est pas nécessaire de lier une handleChangefonction. Lorsque le formulaire est soumis, la valeur sera prise du DOM et les validations nécessaires peuvent avoir lieu à ce stade. Pas besoin de créer de fonctions de gestionnaire pour aucun des composants d'entrée également.

Votre problème

Maintenant, pour votre problème:

... Je veux qu'il soit appelé lorsque je pousse 'Entrée lorsque le numéro entier a été entré

Si vous souhaitez y parvenir, utilisez un composant non contrôlé. Ne créez pas les gestionnaires onChange si ce n'est pas nécessaire. La enterclé soumettra le formulaire et la handleSubmitfonction sera déclenchée.

Changements que vous devez faire:

Supprimez l'appel onChange dans votre élément

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
    //    bsStyle: this.validationInputFactor(),
    placeholder: this.initialFactor,
    className: "input-block-level",
    // onChange: this.handleInput,
    block: true,
    addonBefore: '%',
    ref:'input',
    hasFeedback: true
});

Gérez le formulaire, soumettez et validez votre saisie. Vous devez obtenir la valeur de votre élément dans la fonction de soumission de formulaire, puis valider. Assurez-vous de créer la référence à votre élément dans le constructeur.

  handleSubmit(event) {
      // Get value of input field
      let value = this.input.current.value;
      event.preventDefault();
      // Validate 'value' and submit using your own api or something
  }

Exemple d'utilisation d'un composant non contrôlé:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    // bind submit function
    this.handleSubmit = this.handleSubmit.bind(this);
    // create reference to input field
    this.input = React.createRef();
  }

  handleSubmit(event) {
    // Get value of input field
    let value = this.input.current.value;
    console.log('value in input field: ' + value );
    event.preventDefault();
    // Validate 'value' and submit using your own api or something
  }

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

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);
c-chavez
la source
3

Vous pouvez également écrire une petite fonction wrapper comme celle-ci

const onEnter = (event, callback) => event.key === 'Enter' && callback()

Consommez-le ensuite sur vos entrées

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
David Alsh
la source