使用来自React的a
的html input type=checkbox
-tag有一个奇怪的问题。问题是如果我直接点击复选框而不是a
-tag,复选框将无法正确重新渲染,但我的状态已更新。
示例:根据下面的代码,我渲染组件并直接单击复选框。在这种情况下,showMap将被设置为false,因为我们在构造函数中将其设置为true,但仍然会在html视图中检查复选框。但是,如果我单击a
-tag但不直接在复选框上,则状态showMap以及视图都会正确更新。
我可以通过不在event.preventDefault();
中调用toggleCheckbox
来实现它,但如果我这样做,如果我点击a
-tag,应用程序将滚动到页面顶部。
例:
https://codesandbox.io/s/w2x8vqq8xl
码:
import React from "react";
import { render } from "react-dom";
const styles = {
fontFamily: "sans-serif",
textAlign: "center",
//marginTop: "1000px"
};
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
showMap: true
};
}
toggleCheckbox = event => {
this.setState({ showMap: !this.state.showMap });
event.preventDefault();
};
render() {
return (
<div>
<h1>{this.state.showMap ? "Show" : "hide"}</h1>
<a href="#" role="button" onClick={this.toggleCheckbox}>
<input
type="checkbox"
title="test"
name="showMap"
checked={this.state.showMap}
readOnly
/>
Show map
</a>
</div>
);
}
}
const App = () => (
<div style={styles}>
<Menu />
</div>
);
render(<App />, document.getElementById("root"));
更新:
创建了React的问题。
这似乎是浏览器本机行为:
HTML:
<a href="#" role="button" id="anchor">
<input id="input" type="checkbox" title="test" name="showMap" readonly /> Clicking this text toggles the checkbox
</a>
<hr />
<label><input id="prevent" type="checkbox" /> Prevent Default</label>
<p>With prevent default on, clicking the checkbox does not toggle it. Only clicking the text</p>
CSS:
body {
font-size: 15px;
line-height: 1.5;
padding: 20px;
}
JS:
var anchor = document.getElementById('anchor')
var prevent = document.getElementById('prevent')
var input = document.getElementById('input')
var toggled = false
anchor.addEventListener('click', function (event) {
if (prevent.checked) {
event.preventDefault()
}
toggled = !toggled
input.checked = toggled
})
https://codepen.io/nhunzaker/pen/WXONQK
https://github.com/facebook/react/issues/11539#issuecomment-343914330
而不是在#
中使用href
,你可以在你的javascript:void(0)
标签中使用a
,以避免滚动到顶部。仅当您在单击a
标记时出现滚动问题时,此选项才有用。希望这可以帮助!
而不是使用event.preventDefault()
使用event.stopPropagation()
阅读更多相关信息