web-dev-qa-db-fra.com

React La case à cocher n'envoie pas onChange

TLDR: Utilisez defaultChecked au lieu de coché, fonctionne jsbin .

Essayer de configurer une simple case à cocher qui barrera son libellé quand il sera coché. Pour une raison quelconque, handleChange n'est pas déclenché lorsque j'utilise le composant. Quelqu'un peut-il expliquer ce que je fais mal?

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    console.log('handleChange', this.refs.complete.checked); // Never gets logged
    this.setState({
      complete: this.refs.complete.checked
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            checked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});

Usage:

React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);

Solution:

L'utilisation de vérifié ne laisse pas la valeur sous-jacente changer (apparemment) et n'appelle donc pas le gestionnaire onChange. Passer à defaultChecked semble résoudre ce problème:

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    this.setState({
      complete: !this.state.complete
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            defaultChecked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});
100
jdarling

Pour obtenir l'état coché de votre case à cocher, le chemin serait:

this.refs.complete.state.checked

L'alternative consiste à l'obtenir à partir de l'événement passé dans la méthode handleChange:

event.target.checked
154
zbyte

Il est préférable de ne pas utiliser les références dans de tels cas. Utilisation:

<input
    type="checkbox"
    checked={this.state.active}
    onClick={this.handleClick}
/>

Il y a quelques options:

checked vs defaultChecked

Le premier répondrait aux deux changements d'état et clics. Ce dernier ignorerait les changements d'état.

onClick vs onChange

Le premier déclencherait toujours sur des clics. Ce dernier ne déclencherait pas de clics si l'attribut checked est présent sur l'élément input.

15
Lin

Dans le scénario où vous ne souhaitez PAS utiliser le gestionnaire onChange sur le DOM d'entrée, vous pouvez utiliser la propriété onClick comme alternative. Le defaultChecked, la condition peut laisser un état fixe pour v16 IINM.

 class CrossOutCheckbox extends Component {
      constructor(init){
          super(init);
          this.handleChange = this.handleChange.bind(this);
      }
      handleChange({target}){
          if (target.checked){
             target.removeAttribute('checked');
             target.parentNode.style.textDecoration = "";
          } else {
             target.setAttribute('checked', true);
             target.parentNode.style.textDecoration = "line-through";
          }
      }
      render(){
         return (
            <span>
              <label style={{textDecoration: this.props.complete?"line-through":""}}>
                 <input type="checkbox"
                        onClick={this.handleChange}
                        defaultChecked={this.props.complete}
                  />
              </label>
                {this.props.text}
            </span>
        )
    }
 }

J'espère que cela aidera quelqu'un à l'avenir.

8
akiespenc

Si vous avez une fonction handleChange qui ressemble à ceci:

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

Vous pouvez créer une fonction personnalisée onChange afin qu’elle se comporte comme une entrée de texte:

<input
  type="checkbox"
  name="check"
  checked={this.state.check}
  onChange={(e) => {
    handleChange({
      target: {
        name: e.target.name,
        value: e.target.checked,
      }
    });
  }}
/>
2
spencer.sm

onChange n'appellera pas handleChange sur mobile lors de l'utilisation de defaultChecked. Comme alternative, vous pouvez utiliser onClick et onTouchEnd.

<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete} />;

1
tanner burton

Dans l'interface utilisateur matérielle, l'état de la case à cocher peut être récupéré comme

this.refs.complete.state.switched
1
Sakshi Nagpal