【问题标题】:Default disabled button click event is not firing on reactjs默认禁用按钮单击事件未在 reactjs 上触发
【发布时间】:2018-04-25 14:26:40
【问题描述】:

我有默认禁用的按钮。但是当复选框被选中时,按钮将被启用,使用 ref 我正在启用按钮。按钮激活后单击事件未触发。如果没有默认禁用,按钮的点击事件就会触发。

    class TodoApp extends React.Component {

        onChangeCheckBox(event) {
            if(event.target.checked) {
                this.actionButtonRef.disabled = "";
            }
            else {
                this.actionButtonRef.disabled = "disabled";

            }
        }  

        render() {
            return (
            <div>
                <input 
                    type="checkbox" 
                    ref={element => {
                        this.checkboxAllRef = element;
                    }}
                    onChange={event => this.onChangeCheckBox(event)}/> Checbox 
                <br />
                <button
                    type="button"
                    className="btn btn-danger" 
                    ref={element => {
                        this.actionButtonRef = element;
                    }}
                    onClick={event => {
                        alert("clicked");
                    }} 
                    disabled="disabled">Button</button>
            </div>
            )
        }
    }

    ReactDOM.render(<TodoApp />, document.querySelector("#app"))

here is jsfiddle

【问题讨论】:

标签: reactjs


【解决方案1】:

React 不允许手动修改 DOM 元素(实际上是虚拟 DOM)。

您需要保持启用或禁用状态。并根据状态变化工作:

类构造函数:

  constructor(props) {
    super(props);

    this.state = {
      checked: false
    };

    this.onChangeCheckBox = this.onChangeCheckBox.bind(this);
    this.onClickButton = this.onClickButton.bind(this);
  }

事件处理程序:

  onChangeCheckBox(e) {
    this.setState({
      checked: e.target.checked,
    });
  }
  onClickButton(e) {
    alert(e);
  }

渲染 JSX:

  render() {
    return (
      <div>
        <input
          type="checkbox"
          checked={this.state.checked}
          onChange={this.onChangeCheckBox}
        />
        <button
          type="button"
          disabled={!this.state.checked}
          onClick={this.onClickButton}>Click</button>
      </div>
    );
  }
}

这是demo

【讨论】:

  • 感谢您的回答。我知道我们可以通过使用状态来做到这一点。但问题是,当按钮被禁用/启用时,我不想重新渲染组件。这是实现它的唯一方法吗?而且我还知道我单击事件未触发的原因。因为我找不到任何原因
  • 见粗体字。所以,如果你不想重新渲染,那么你可以在使用/更新状态时使用 shouldComponentUpdate 钩子。
  • 但是当我使用 ref 更改文本框值时,它在没有组件重新渲染的情况下被更改。还使用 ref 启用了按钮,但未触发 click 事件。这让我很困惑
  • 这就是问题所在。 React 不允许你手动修改 dom。
  • 所以我可以这样考虑。使用 ref 我们可以更改属性,但如果不重新渲染,事件将不会更新
【解决方案2】:

试试这个JSfiddle link

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      //Set initial state here
      btnDisabled: true
    };
  }
  onChangeCheckBox(event) {
    if (event.target.checked) {
      this.setState({ btnDisabled: false }); //Set new state here
    } else {
      this.setState({ btnDisabled: true });  //Set new state here
    }
  }
  render() {
    return (
      <div>
        <input
          type="checkbox"
          onChange={event => this.onChangeCheckBox(event)}
        />{" "}
        Checbox
        <div>
          <button
            type="button"
            className="btn btn-danger"
            onClick={event => {
              alert("clicked");
            }}
            disabled={this.state.btnDisabled}  //Always use state 
          >
            Button
          </button>
        </div>
      </div>
    );
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"));

您的组件没有重新渲染,因为您没有在单击复选框时调用 setstate。单击复选框时,您需要调用 setState 并设置 btnDisabled

当 setState 发生时,reactjs 会重新渲染组件。这样做会启用按钮。

你不应该在 React 中过度使用 refs。

应谨慎使用引用 另请参阅此答案以了解禁用按钮 how-to-disable-button-in-react-js

的最佳做法

【讨论】:

  • 感谢您的回答。我知道我们可以通过使用状态来做到这一点。但问题是,当按钮被禁用/启用时,我不想重新渲染组件。这是实现它的唯一方法吗?而且我知道为什么我点击事件没有触发的原因。因为我找不到任何原因
  • @Sivabalan 在你的问题中,你使用 refs 来改变按钮的 disabled 属性,你通过更新 DOM 改变了它,但反应不知道。
  • 当你点击它时,反应仍然认为按钮被禁用
  • 通过使用 setstate,你告诉 react 更新 DOM。在那之前你是自己更新的。
  • 但是当我使用 ref 更改文本框值时,它在没有组件重新渲染的情况下被更改。还使用 ref 启用了按钮,但未触发 click 事件。这让我很困惑
【解决方案3】:

您应该尝试使用值truefalse 作为按钮上disabled 属性的值,而不是disabled""

如果这些设置不正确,按钮将无法在禁用和不正确之间正确切换,因此您将无法执行点击事件。

另一方面,通常认为最好的做法是尽可能少地使用 refs,您可以通过使用 state 在 true 和 false 之间切换来获得类似的、更理想的结果

【讨论】:

  • 感谢您的回答。但即使将值更改为 true 和 false 也不起作用
猜你喜欢
  • 2013-05-11
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2013-01-17
  • 2012-03-14
  • 2011-12-02
  • 2013-10-14
相关资源
最近更新 更多