【问题标题】:React div container onClick conflicts with checkbox onChange反应 div 容器 onClick 与复选框 onChange 冲突
【发布时间】:2016-04-11 04:43:48
【问题描述】:

在下面的 React 类中,我在 div 容器中有一个复选框。我想点击容器来切换复选框。我还认为我需要绑定复选框输入本身的 onChange,以处理当用户使用制表符/间距来切换复选框状态时(如果我也收到来自 React 的警告) 不要指定 onChange,因为这是一个受控组件。

我的问题是,当我单击复选框本身时,两个 事件处理程序都会触发,因此复选框的状态实际上并没有改变。我在 handleCheckboxChange 中尝试了 e.preventDefault 和 e.stopPropagation 但似乎都没有做任何事情。

export default class Item extends React.Component{
    constructor(){
        super();
        this.state={
            IsSelected: false
        }
    }
    render(){
        return (
            <div className="item">
                <div className="checkbox-container" onClick={this.handleContainerClick.bind(this)}>
                    <input type="checkbox" checked={this.state.IsSelected} onChange={this.handleCheckboxChange.bind(this)} />
                </div>                  
            </div>
        );
    }
    handleCheckboxChange(e){
        this.setState({
            IsSelected: !this.state.IsSelected
        });
    }
    handleContainerClick(){
        this.setState({
            IsSelected: !this.state.IsSelected
        });     }
}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    如果您希望包含的&lt;div&gt; 能够“控制”复选框的值,则不要在复选框本身上放置任何处理程序。 React 将确保容器将收到子 click 事件。

    var CheckboxInClickableBox = React.createClass({
      getInitialState: function () {
        return {
          checked: false
        };
      },
      render: function () {
        return (
          <div onClick={this.onClick}>
            <span>{"Checked: " + this.state.checked}</span>
    
            <br />
    
            <input type="checkbox" checked={this.state.checked} />
          </div>
        );
      },
      onClick: function () {
        this.setState({
          checked: !this.state.checked
        });
      }
    });
    

    Example on JSBin - 单击绿色框中的任意位置将触发切换。

    此外,HTML 规定带有for="pie" 属性的&lt;label&gt; 会将click 事件传递给任何&lt;input id="pie"&gt;。使用上述方法时,这似乎会“破坏”您的复选框 - 例如:

      render: function () {
        return (
          <div onClick={this.onClick}>
            <label htmlFor="pie">{"Checked: " + this.state.checked}</label>
    
            <br />
    
            <input id="pie" type="checkbox" checked={this.state.checked} />
          </div>
        );
      }
    

    单击&lt;label&gt; 的行为就像有 2 个单击事件:

    • 第一个是原始的click 事件从&lt;label&gt; 冒泡到&lt;div&gt; 并触发我们的onClick 处理程序
    • 第二个是&lt;label&gt;“委托”它的点击到&lt;input&gt;元素,由于for属性(htmlFor在React中),然后冒泡并命中我们的onClick处理程序李>

    Example on JSBin - 点击框中的任意位置&lt;label&gt; 将触发切换。单击&lt;label&gt; 将触发 2 个切换。

    【讨论】:

    • 仅在 div 上设置 onClick 的一个问题是,React 总是会记录一个关于在没有 onChange 处理程序的情况下输入的警告。既然您提到了 htmlFor 属性,我认为正确的做法是将我的容器设置为
    • 很高兴我能帮上忙。关于onChange 处理程序:只有当您跳过onChange 处理程序并提供value 属性时,React 提供的警告才会出现,因为具有静态值的input 可能(尽管并非总是)指示设计缺陷。例如,当我忘记在输入中添加 onChange={this.onChange} 时,此警告对我有所帮助。
    • 对,但在这种情况下,我提供了一个 value 属性,因为这是一个受控组件。
    • @Sean 我遇到了一个类似的用例,我通过在复选框中添加一个 readOnly 属性来解决它。
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多