如何在React.js中禁用按钮

时间:2017-01-05 15:27:45

标签: javascript reactjs

我有这个组件:

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:无法读取未定义的属性“value”

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

9 个答案:

答案 0 :(得分:41)

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

每次输入字段更改时,您都可以使用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} />

这是一个有效的例子:

&#13;
&#13;
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')
);
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:10)

在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>
    );
}

答案 2 :(得分:5)

您不应该通过参考设置输入值。

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

简而言之

if info['max']=='catarro':
    poly = Polygon(shape, facecolor = "#DDDDDD", alpha = alpha, linewidtt = 0.01)
    plt.gca().add_patch(poly)

然后,您将能够使用<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} />

来控制禁用状态

答案 3 :(得分:2)

在调用textField.text = "Test" 回调之前,

this.input未定义。尝试在构造函数中将ref设置为某个初始值。

来自the React docs on refs,强调我的:

  

在装载或卸载组件后,将立即执行回调

答案 4 :(得分:1)

我们在React中控制组件渲染的方法很少见。 enter image description here

但是,我没有在这里使用任何这些,我只是使用ref来将基础子命名空间命名为组件。

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>

答案 5 :(得分:0)

我遇到了类似的问题,事实证明我们不需要钩子即可完成这些操作,我们可以进行条件渲染,并且仍然可以正常工作。

<Button
    type="submit"
    disabled={
        name === "" || email === "" || password === "" ? true : false
    }
    fullWidth
    variant="contained"
    color="primary"
    className={classes.submit}>
    SignUP
</Button>

答案 6 :(得分:0)

只需添加:

<button disabled={this.input.value?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>

答案 7 :(得分:0)

对此非常简单的解决方案是使用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

启用按钮

答案 8 :(得分:0)

这是一个使用 React 钩子的函数式组件。

我提供的示例代码应该足够通用,可以修改特定用例或搜索“如何禁用 React 中的按钮”并登陆这里的任何人。

import React, { useState } from "react";

const YourComponent = () => {
  const [isDisabled, setDisabled] = useState(false);
  
  const handleSubmit = () => {
    console.log('Your button was clicked and is now disabled');
    setDisabled(true);
  }

  return (
      <button type="button" onClick={handleSubmit} disabled={isDisabled}>
        Submit
      </button>
  );
}

export default YourComponent;