web-dev-qa-db-fra.com

Impossible de saisir React champ de texte de saisie

J'essaie mon premier morceau de React.js et je suis perplexe tôt ... J'ai le code ci-dessous, qui convertit un formulaire de recherche en <div id="search"></div>. Mais taper dans le champ de recherche ne fait rien.

Vraisemblablement, il manque quelque chose en passant à côté des accessoires et des états, et cela semble être un problème courant. Mais je suis perplexe - je ne peux pas voir ce qui manque.

var SearchFacet = React.createClass({
  handleChange: function() {
    this.props.onUserInput(
      this.refs.searchStringInput.value
    )
  },
  render: function() {
    return (
      <div>
        Search for:
        <input
          type="text"
          value={this.props.searchString}
          ref="searchStringInput"
          onchange={this.handleChange} />
      </div>
    );
  }
});

var SearchTool = React.createClass({
  render: function() {
    return (
      <form>
        <SearchFacet 
          searchString={this.props.searchString}
          onUserInput={this.props.onUserInput}
         />
        <button>Search</button>
      </form>
    );
  }
});

var Searcher = React.createClass({
  getInitialState: function() {
    return {
      searchString: ''
    }
  },

  handleUserInput: function(searchString) {
    this.setState({
      searchString: searchString
    })
  },

  render: function() {
    return (
      <div>
        <SearchTool 
          searchString={this.state.searchString}
          onUserInput={this.handleUserInput}
        />
      </div>
    );
  }
});

ReactDOM.render(
  <Searcher />,
  document.getElementById('searcher')
);

(J'aurai éventuellement d'autres types de SearchFacet* mais j'essaie simplement de faire fonctionner celui-ci.)

84
Phil Gyford

Vous n'avez pas correctement mis votre onchange accessoire dans la input. Il doit être onChange dans JSX.

<input
  type="text"
  value={this.props.searchString}
  ref="searchStringInput"
  onchange={this.handleChange} <--[should be onChange]
/>  

Le sujet de passer un value accessoire à un <input>, puis de modifier en quelque sorte la valeur transmise en réponse à une interaction utilisateur à l'aide d'un gestionnaire onChange est assez bien considéré dans le fichier docs .

Elles se réfèrent à des entrées telles que Composants contrôlés , et font référence à des entrées qui laissent le DOM gérer de manière native la valeur de l'entrée et les modifications ultérieures de l'utilisateur sous la forme Composants non contrôlés .

Chaque fois que vous définissez la propriété value d'un input sur une variable, , vous avez un composant contrôlé . Cela signifie que vous devez modifier la valeur de la variable par un moyen programmatique, sinon l'entrée contiendra toujours cette valeur et ne changera jamais, même lorsque vous tapez - le comportement natif de l'entrée, pour mettre à jour sa valeur lors de la frappe, est remplacée par React ici.

Donc, vous prenez correctement cette variable de l’état, et vous avez un gestionnaire pour mettre à jour l’état correctement. Le problème vient du fait que vous avez onchange et que vous n’avez pas le bon onChange le gestionnaire n’a jamais été appelé. Le value n’a donc jamais été mis à jour lorsque vous tapez dans l’entrée. Lorsque vous utilisez onChange le gestionnaire est appelé appelé, le value est mis à jour lorsque vous tapez, et vous voyez vos changements.

65
davnicwil

En utilisant value={whatever}, vous ne pourrez plus taper dans le champ de saisie. Vous devriez utiliser defaultValue="Hello!".

Voir https://facebook.github.io/react/docs/uncontrolled-components.html#default-values

De plus, la onchange devrait être onChange comme le fait remarquer @davnicwil.

162
Ivan

Cela peut être dû au fait que la fonction onChange ne met pas à jour la valeur correcte mentionnée dans l'entrée.

Exemple:

<input type="text" value={this.state.textValue} onChange = {this.changeText}></input>

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

dans la fonction onChange, mettez à jour le champ de valeur mentionné.

7
sunaina kotekar

J'ai également le même problème et dans mon cas, j'ai injecté le réducteur correctement mais je ne pouvais toujours pas taper sur le terrain. Il s'avère que si vous utilisez immutable, vous devez utiliser redux-form/immutable.

import {reducer as formReducer} from 'redux-form/immutable';
const reducer = combineReducers{

    form: formReducer
}
import {Field, reduxForm} from 'redux-form/immutable';
/* your component */

Notez que votre état doit être comme state->form sinon vous devez explicitement configurer la bibliothèque et le nom de l'état doit être form. voir ceci issue

4