TL;DR: используйте defaultChecked вместо отмеченного, работая jsbin здесь http://jsbin.com/mecimayawe/1/edit?js,output
Попытка установить простой флажок, который будет вычеркнуть текст его метки, когда он будет установлен. По какой-то причине handleChange не запускается, когда я использую компонент. Может ли кто-нибудь объяснить, что я делаю неправильно?
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>
);
}
});
Использование:
React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);
Решение:
Использование checked не позволяет изменять базовое значение (по-видимому) и, следовательно, не вызывает обработчик onChange. Переключение на defaultChecked похоже на исправление:
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>
);
}
});
Чтобы получить проверенное состояние вашего флажка, путь будет следующим:
this.refs.complete.state.checked
Альтернативой является получение его из события, переданного в метод handleChange
:
event.target.checked
В таких случаях лучше не использовать ссылки. Использование:
<input
type="checkbox"
checked={this.state.active}
onClick={this.handleClick}
/>
Есть несколько вариантов:
checked
против defaultChecked
Первый будет реагировать как на изменения состояния, так и на клики. Последний будет игнорировать изменения состояния.
onClick
против onChange
Первый всегда будет срабатывать при кликах. Последний не будет срабатывать при щелчках, если checked
атрибут присутствует в элементе input
.
В сценарии, который вы НЕ хотели бы использовать обработчик onChange на входной DOM, вы можете использовать свойство onClick
в качестве альтернативы. defaultChecked
может оставить фиксированное состояние для 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>
)
}
}
Я надеюсь, что это поможет кому-то в будущем.
onChange не будет вызывать handleChange на мобильном телефоне при использовании defaultChecked. В качестве альтернативы вы можете использовать onClick и onTouchEnd.
<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete}/>;
Если у вас есть функция handleChange
которая выглядит следующим образом:
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
}
Вы можете создать пользовательскую функцию onChange
чтобы она onChange
так, как если бы ввод текста:
<input
type="checkbox"
name="check"
checked={this.state.check}
onChange={(e) => {
handleChange({
target: {
name: e.target.name,
value: e.target.checked,
}
});
}}
/>
handleChange
на input
должно быть this.handleChange
?
В материале ui состояние флажка может быть выбрано как
this.refs.complete.state.switched
this.setState({checked: !this.state.checked})
проще, чем хранить значение. Тогда троичный оператор в проверенном атрибуте:checked={this.state.checked ? 'checked': null}