简体   繁体   English

如何在 React.js 中禁用按钮

[英]How to disable button in React.js

I have this component:我有这个组件:

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

}

I want the button to be disabled when input value is empty.我希望在输入值为空时禁用按钮。 But the code above doesn't work.但是上面的代码不起作用。 It says:它说:

add-item.component.js:78 Uncaught TypeError: Cannot read property 'value' of undefined add-item.component.js:78 Uncaught TypeError: 无法读取未定义的属性“值”

pointing to disabled={.this.input.value} .指向disabled={.this.input.value} What can I be doing wrong here?我在这里做错了什么? I'm guessing that perhaps ref isn't created yet when render method is executed.我猜当render方法执行时,可能 ref 还没有创建。 If, so what is the workararound?如果,那么解决方法是什么?

Using refs is not best practice because it reads the DOM directly, it's better to use React's state instead.使用refs不是最佳实践,因为它直接读取 DOM,最好改用 React 的state Also, your button doesn't change because the component is not re-rendered and stays in its initial state.此外,您的按钮不会更改,因为组件不会重新呈现并保持其初始状态。

You can use setState together with an onChange event listener to render the component again every time the input field changes:您可以将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} />

Here's a working example:这是一个工作示例:

 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>

In HTML,在 HTML 中,

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

All of them boils down to disabled="true" that is because it returns true for a non-empty string.所有这些都归结为 disabled="true" 这是因为它为非空字符串返回 true。 Hence, in order to return false, pass a empty string in a conditional statement like this.input.value?"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>
    );
}

You shouldn't be setting the value of the input through refs.您不应该通过 refs 设置输入的值。

Take a look at the documentation for controlled form components here - https://facebook.github.io/react/docs/forms.html#controlled-components在此处查看受控表单组件的文档 - https://facebook.github.io/react/docs/forms.html#controlled-components

In a nutshell简而言之

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

Then you will be able to control the disabled state by using disabled={!this.state.value}然后你就可以使用disabled={!this.state.value}来控制禁用状态

There are few typical methods how we control components render in React.我们在 React 中控制组件渲染的典型方法很少。 在此处输入图片说明

But, I haven't used any of these in here, I just used the ref's to namespace underlying children to the component.但是,我在这里没有使用任何这些,我只是使用了 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>

this.input is undefined until the ref callback is called.在调用ref回调之前, this.input是未定义的。 Try setting this.input to some initial value in your constructor.尝试在构造函数this.input设置为某个初始值。

From the React docs on refs , emphasis mine:关于 refs 的 React 文档中,强调我的:

the callback will be executed immediately after the component is mounted or unmounted回调会在组件挂载或卸载立即执行

I have had a similar problem, turns out we don't need hooks to do these, we can make an conditional render and it will still work fine.我遇到了类似的问题,结果证明我们不需要钩子来做这些,我们可以进行条件渲染,它仍然可以正常工作。

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

very simple solution for this is by using useRef hook非常简单的解决方案是使用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>

Similarly you can enable the button by using buttonRef.current.disabled = false同样,您可以使用buttonRef.current.disabled = false启用按钮

Here is a functional component variety using react hooks.这是一个使用 React 钩子的功能组件。

The example code I provided should be generic enough for modification with the specific use-case or for anyone searching "How to disable a button in React" who landed here.我提供的示例代码应该足够通用,可以修改特定用例或搜索“如何禁用 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;

只需添加:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM