【问题标题】:React 16 input type=checkbox not rendered correctly if nested in html a-tag如果嵌套在 html a-tag 中,React 16 输入类型 = 复选框未正确呈现
【发布时间】:2017-11-13 06:57:21
【问题描述】:

我在使用来自 React 的 a-tag 和 input type=checkbox 时遇到了一个特殊的问题。问题是,如果我直接点击复选框而不是 a-tag,复选框将无法正确重新呈现,但我的状态已更新。

示例:给定下面的代码,我渲染组件并直接单击复选框。在这种情况下,showMap 将设置为 false,因为我们在构造函数中将其设置为 true,但在 html 视图中仍会选中复选框。但是,如果我单击 a-tag 而不是直接单击复选框,则状态 showMap 和视图都会正确更新。

我可以通过不在toggleCheckbox 中调用event.preventDefault(); 来使其工作,但如果我这样做,如果我点击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

【问题讨论】:

  • 它看起来完全像一个 reactjs 错误。如果您举报,请在问题中添加链接。
  • @zerkms 我怀疑这一点。创建问题并使用链接更新问题。

标签: javascript html reactjs typescript typescript2.0


【解决方案1】:

这似乎是浏览器原生行为:

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

【讨论】:

    【解决方案2】:

    您可以在a-tag 中使用javascript:void(0) 而不是在href 中使用#,以避免滚动到顶部。仅当您在单击 a 标记时遇到滚动问题时,这才有用。希望这会有所帮助!

    【讨论】:

    • 谢谢,但我不想解决它,也不是黑客。 :)
    【解决方案3】:

    不要使用event.preventDefault(),而是使用event.stopPropagation()

    阅读更多关于此的信息

    https://medium.com/@jacobwarduk/how-to-correctly-use-preventdefault-stoppropagation-or-return-false-on-events-6c4e3f31aedb

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-09
      • 2015-10-14
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 2017-07-13
      相关资源
      最近更新 更多