我在使用 html a
-tag 和 React 的 input type=checkbox
时遇到了一个特殊的问题。问题是,如果我直接单击复选框而不是 a
-tag,复选框将无法正确重新渲染,但我的状态已更新。
示例:给定下面的代码,我渲染组件并直接单击复选框。在这种情况下,showMap 将设置为 false,因为我们在构造函数中将其设置为 true,但在 html 视图中仍会选中该复选框。但是,如果我单击a
-tag而不是直接单击复选框,则状态显示映射和视图都会正确更新。
我可以通过不调用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 上创建了一个问题。
https://github.com/facebook/react/issues/11539
似乎是浏览器原生行为:
.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
您可以在 a
-tag 中使用javascript:void(0)
,而不是在 href
中使用 #
以避免滚动到顶部。仅当您在单击标记时遇到滚动问题时a
这才有用。希望这有帮助!
与其使用event.preventDefault()
不如使用event.stopPropagation()
阅读更多相关信息,请访问
https://medium.com/@jacobwarduk/how-to-correctly-use-preventdefault-stoppropagation-or-return-false-on-events-6c4e3f31aedb