如何在 React.js 中禁用按钮

IT技术 javascript reactjs
2021-03-03 04:05:44

我有这个组件:

import React from 'react';

export default class AddItem extends React.Component {

add() {
    this.props.onButtonClick(this.input.value);
    this.input.value = '';
}


render() {
    return (
        <div className="add-item">
            <input type="text" className="add-item__input" ref={(input) => this.input = input} placeholder={this.props.placeholder} />
            <button disabled={!this.input.value} className="add-item__button" onClick={this.add.bind(this)}>Add</button>
        </div>
    );
}

}

我希望当输入值为空时禁用按钮。但是上面的代码不起作用。它说:

add-item.component.js:78 Uncaught TypeError: 无法读取未定义的属性“值”

指向disabled={!this.input.value}. 我在这里做错了什么?我猜可能在render执行方法时还没有创建 ref 如果,那么解决方法是什么?

6个回答

使用refs不是最佳实践,因为它直接读取 DOM,最好使用 Reactstate代替。此外,您的按钮不会更改,因为组件不会重新渲染并保持其初始状态。

每次输入字段更改时,您都可以setStateonChange事件侦听器一起使用以再次呈现组件:

// Input field listens to change, updates React's state and re-renders the component.
<input onChange={e => this.setState({ value: e.target.value })} value={this.state.value} />

// Button is disabled when input state is empty.
<button disabled={!this.state.value} />

这是一个工作示例:

class AddItem extends React.Component {
  constructor() {
    super();
    this.state = { value: '' };
    this.onChange = this.onChange.bind(this);
    this.add = this.add.bind(this);
  }

  add() {
    this.props.onButtonClick(this.state.value);
    this.setState({ value: '' });
  }

  onChange(e) {
    this.setState({ value: e.target.value });
  }

  render() {
    return (
      <div className="add-item">
        <input
          type="text"
          className="add-item__input"
          value={this.state.value}
          onChange={this.onChange}
          placeholder={this.props.placeholder}
        />
        <button
          disabled={!this.state.value}
          className="add-item__button"
          onClick={this.add}
        >
          Add
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <AddItem placeholder="Value" onButtonClick={v => console.log(v)} />,
  document.getElementById('View')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='View'></div>

这是正确答案!内部状态应该用于更新输入的变化,按钮应该简单地检查这一点。+1
2021-04-28 04:05:44
@Adrianopolis React 会disabled从 DOM 中删除属性,如果它被设置为false——这是跨浏览器友好的。
2021-04-30 04:05:44
this.state 有一个限制,它会再次呈现 UI,因此如果您在子组件的文本框中键入内容并绑定到 onChange 事件,它会从文本框中失去焦点。如果它在同一个组件中,那很好,但是当在子组件中使用时,它会失去焦点。
2021-05-06 04:05:44
@Adrianopolis 我不知道该告诉你什么。与您的检查员一起查看实际运行的演示代码。React 正在删除该disabled属性。这是 JSX,不是 HTML。这里没有问题。
2021-05-12 04:05:44
@Dynamic 这不应该发生。你有这样的工作例子吗?
2021-05-13 04:05:44

在 HTML 中,

<button disabled/>
<buttton disabled="true">
<buttton disabled="false">
<buttton disabled="21">

所有这些都归结为 disabled="true" 这是因为它为非空字符串返回 true。因此,为了返回 false,请在像this.input.value?"true":""这样的条件语句中传递一个空字符串

render() {
    return (
        <div className="add-item">
            <input type="text" className="add-item__input" ref={(input) => this.input = input} placeholder={this.props.placeholder} />
            <button disabled={this.input.value?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>
        </div>
    );
}
如果堆栈溢出有支持答案的选项,我会选择这个答案
2021-04-28 04:05:44
buttton这里拼写错误吗?
2021-05-02 04:05:44

您不应该通过 refs 设置输入的值。

在此处查看受控表单组件的文档 - https://facebook.github.io/react/docs/forms.html#controlled-components

简而言之

<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} />

然后您将能够通过使用控制禁用状态 disabled={!this.state.value}

我们在 React 中控制组件渲染的典型方法很少。 在此处输入图片说明

但是,我在这里没有使用任何这些,我只是使用了引用的命名空间底层子组件的组件。

class AddItem extends React.Component {
    change(e) {
      if ("" != e.target.value) {
        this.button.disabled = false;
      } else {
        this.button.disabled = true;
      }
    }

    add(e) {
      console.log(this.input.value);
      this.input.value = '';
      this.button.disabled = true;
    }

    render() {
        return (
          <div className="add-item">
          <input type="text" className = "add-item__input" ref = {(input) => this.input=input} onChange = {this.change.bind(this)} />
          
          <button className="add-item__button" 
          onClick= {this.add.bind(this)} 
          ref={(button) => this.button=button}>Add
          </button>
          </div>
        );
    }
}

ReactDOM.render(<AddItem / > , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

非常简单的解决方案是使用useRef钩子

const buttonRef = useRef();

const disableButton = () =>{
  buttonRef.current.disabled = true; // this disables the button
 }

<button
className="btn btn-primary mt-2"
ref={buttonRef}
onClick={disableButton}
>
    Add
</button>

同样,您可以通过使用启用按钮 buttonRef.current.disabled = false