我很惊讶复选框功能不是我预期的。如果我有一个带有onClick
的包装器div,并单击除复选框之外的任何内容,它将按预期工作。但是,当我单击复选框时,即使传递的propp确实更新,复选框也保持相同的状态。我的猜测是,在推文改变被推下之后,复选框正在触发其内部更新事件。
const ToDo = (props) => {
const { title, done, onChange } = props;
const handleChange = (event) => {
event.preventDefault();
if (onChange) {
onChange(!done)
}
}
return (
<div onClick={handleChange}>
<label>
<input type="checkbox" checked={done}/> {title}
</label>
</div>
);
};
我想知道处理这个问题的正确方法是什么?
答案 0 :(得分:1)
似乎正在发生的事情是,当您点击标签时,它会调用复选框的onChange
功能以及div onClick
。< / p>
解决这个问题的一个简单方法是禁用标签上的指针事件,因此只调用onClick
(我假设有一些原因你需要在父代onClick
而不是onChange
1}}在输入本身上。)
可能还有另一种方法可以阻止事件传播,但是你必须处理多个处理程序,所以css方式似乎很容易解决。
这是一个演示:
class App extends React.Component {
state = {
done: false
}
onCheckDone = (done) => {
this.setState({
done
});
}
render() {
return (
<ToDo
title="hello"
done={this.state.done}
onChange={this.onCheckDone}
/>
);
}
}
const ToDo = (props) => {
const { title, done, onChange } = props;
const handleChange = (event) => {
event.stopPropagation();
if (onChange) {
onChange(!done)
}
}
return (
<div className="clicker" onClick={handleChange}>
<label>
<input type="checkbox" checked={done} /> {title}
</label>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById('app')
);
&#13;
.clicker {
border: solid 1px #ccc;
padding: 10px 20px;
}
label {
pointer-events: none;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
答案 1 :(得分:0)
这是我发现的简单和有效的解决方法。传递一个不同的键key={done}
将强制将复选框组件重新渲染为另一个dom项,因此它可以工作,但似乎应该有更好的方法来执行此操作。我知道在使用文本输入时不需要这样做,因为值仍然是道具传递下来的。
const ToDo = (props) => {
const { title, done, onChange } = props;
const handleChange = (event) => {
event.preventDefault();
if (onChange) {
onChange(!done)
}
}
return (
<div onClick={handleChange}>
<label>
<input key={done} type="checkbox" checked={done}/> {title}
</label>
</div>
);
};