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>
);
}
});
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
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
.
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.
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,
}
});
}}
/>
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} />;
Dans l'interface utilisateur matérielle, l'état de la case à cocher peut être récupéré comme
this.refs.complete.state.switched