您是否要请求功能或报告错误?
臭虫!
目前的行为是什么?
使用onClick
和onChange
处理程序呈现类型checkbox
的input
元素时,即使event.preventDefault()
仍会调用onChange
event.preventDefault()
在onClick
处理程序中调用。
如果当前行为是错误,请通过https://jsfiddle.net或类似文件(模板:https://jsfiddle.net/reactjs/69z2wepo/)提供重现步骤,并尽可能提供问题的最小演示。
预期的行为是什么?
在onClick
处理程序中调用event.preventDefault
应该可以防止发生默认操作(或撤消其效果),该操作将更新input
元素的值。 这应该阻止任何change
事件侦听器被调用。 请参阅https://jsfiddle.net/L1eskzsq/了解预期行为
哪个版本的React,以及哪个浏览器/操作系统受此问题影响?
使用来自主版本macOS 10.12.2的构建进行了测试,并在以下方面进行了验证:
两种情况下,Safari 10.0.2都会调用change
事件监听器。
该change
正在被创建的事件ChangeEventPlugin
为响应topChange
,在你的onClick
处理甚至被称为(所以之前preventDefault
电话),在这里: https :
该插件试图确定复选框的值是否会更改,如果是,它将在change
事件中排队。 它使用inputValueTracking
功能将上一个值与下一个值进行比较,以做出此决定,在这里: https :
nextValue
像这样直接从DOM中获取: value = isCheckable(node) ? '' + node.checked : node.value;
https://github.com/facebook/react/blob/master/src/renderers/dom/shared/inputValueTracking.js# L56
问题在于,此时的node.checked
值暂时为true,因此在首次单击后为:
lastValue == false
(正确)
nextValue == true
(不正确)
并再次单击复选框,将不再触发change
事件,因为这些值是:
lastValue == true
(不正确)
nextValue == true
(不正确)
总体而言,问题似乎是React可以在调用onClick
的preventDefault之前询问DOM节点的checked
值是什么。
感谢@karelskopek和@Mintaffee在此方面的帮助。
@aweary您认为这值得解决吗?
这个没有进展吗? 我正在使用React v16.2,并且行为相同-首次触发onChange,而随后的点击不会触发它。 我会在这里说非常优先的问题。
有关系吗在复选框onChange
preventDefault
调用https :
在React 16.8.6中仍然是一个问题。 一种可能的解决方法是在onClick
处理程序中执行所有操作:
const radios = ['one', 'two', 'three'];
class Row extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.onChange = this.onChange.bind(this);
}
render() {
const { value } = this.props;
return (
<div className="row">
<div className="radio-group">
{radios.map(radio => (
<label key={radio} className="radio">
<input
type="radio"
name="radio"
value={radio}
checked={radio === value}
onClick={this.onClick}
onChange={this.onChange}
/><span>Radio</span>
</label>
))}
</div>
</div>
);
}
onClick(event) {
// Check something to prevent radio change
if (...) {
event.preventDefault();
return;
}
// Sync value in the store
this.props.setValue(event.target.value);
}
onChange() {
// We need this empty handler to suppress React warning:
// "You provided a `checked` prop to a form field without an `onChange` handler.
// This will render a read-only field. If the field should be mutable use `defaultChecked`.
// Otherwise, set either `onChange` or `readOnly`"
}
}
如果您使用受控组件,我发现的另一个选择是简单地将value保持不变:
onChange(event) {
// Check something to prevent radio change
if (...) {
return;
}
// Sync value in the store
this.props.setDateTime(event.target.value);
}
对于更简单的解决方案,您可以在onMouseDown事件上执行e.preventDefault以防止触发onChange。
onMouseDown(e) {
if (...) {
e.preventDefault();
return;
}
}
最有用的评论
有关系吗在复选框
onChange
preventDefault
调用https :