React 16 输入类型=复选框如果嵌套在 html a 标签中,则无法正确呈现



我在使用 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

最新更新