191

I'm trying to disable a button when an input field is empty. How can I do this in React?

I'm doing something like the following:

<input ref="email"/>

<button disabled={!this.refs.email}>Let me in</button>

Is this correct?

It's not just duplication of the dynamic attribute, because I'm also curious about transferring/checking the data from one element to another.

1

7 Answers 7

283

You'll need to keep the current value of the input in state (or pass changes in its value up to a parent via a callback function, or sideways, or <your app's state management solution here> such that it eventually gets passed back into your component as a prop) so you can derive the disabled prop for the button.

Example using state:

<meta charset="UTF-8">
<script src="https://fb.me/react-0.13.3.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<div id="app"></div>
<script type="text/jsx;harmony=true">void function() { "use strict";

var App = React.createClass({
  getInitialState() {
    return {email: ''}
  },
  handleChange(e) {
    this.setState({email: e.target.value})
  },
  render() {
    return <div>
      <input name="email" value={this.state.email} onChange={this.handleChange}/>
      <button type="button" disabled={!this.state.email}>Button</button>
    </div>
  }
})

React.render(<App/>, document.getElementById('app'))

}()</script>

Sign up to request clarification or add additional context in comments.

9 Comments

Awesome, the example runs and everything. Nice complete example and nice interactive demo, SO.
This wont work because disabled, by merely being attached to an element, means that the element is to be disabled. Its not a bool. See this: developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/…
@Kayote that is not true for React. Those tags are not HTML, they're JSX. And in JSX, if an attribute is assigned false, it is removed entirely when converting to HTML. Did you just ignore the comment immediately above yours that says that it runs perfectly?
@BenBaron thanks for the clarification. I do not remember where / how I used it, however, I had a few issues. Im upvoting your comment so others know that this method is the correct method based on people's experience.
@Kayote Thanks and sorry if I came off a bit rude with the last part of the comment. It was a really long day.
|
13

Using constants allows to combine multiple fields for verification:

class LoginFrm extends React.Component {
  constructor() {
    super();
    this.state = {
      email: '',
      password: '',
    };
  }
  
  handleEmailChange = (evt) => {
    this.setState({ email: evt.target.value });
  }
  
  handlePasswordChange = (evt) => {
    this.setState({ password: evt.target.value });
  }
  
  handleSubmit = () => {
    const { email, password } = this.state;
    alert(`Welcome ${email} password: ${password}`);
  }
  
  render() {
    const { email, password } = this.state;
    const enabled =
          email.length > 0 &&
          password.length > 0;
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Email"
          value={this.state.email}
          onChange={this.handleEmailChange}
        />
        
        <input
          type="password"
          placeholder="Password"
          value={this.state.password}
          onChange={this.handlePasswordChange}
        />
        <button disabled={!enabled}>Login</button>
      </form>
    )
  }
}

ReactDOM.render(<LoginFrm />, document.body);
<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>
<body>


</body>

Comments

9

Another way to check is to inline the function, so that the condition will be checked on every render (every props and state change)

const isDisabled = () => 
  // condition check

This works:

<button
  type="button"
  disabled={this.isDisabled()}
>
  Let Me In
</button>

but this will not work:

<button
   type="button"
   disabled={this.isDisabled}
>
  Let Me In
</button>

Comments

2
const Example = () => {
  
const [value, setValue] = React.useState("");

function handleChange(e) {
    setValue(e.target.value);
  }

return (


<input ref="email" value={value} onChange={handleChange}/>
<button disabled={!value}>Let me in</button> 

);

}
 
export default Example;

1 Comment

While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
0
<button disabled={false}>button WORKS</button>
<button disabled={true}>button DOES NOT work</button>

Now just use useState or any other condition to pass true/false into the button, assuming you are using React.

Comments

-1

Another option to "disable" the button which doesn't require tracking state or explaining to the user why the button is grayed out, is to use the HTML5 required attribute on the input so the button will not submit. docs

<input type="text" required />

enter image description here

2 Comments

This will not disable the button; the button will simply not submit the form when clicked. There is a difference. The most obvious being that the CSS :disabled selector won't work on the button. You could use form:invalid button or similar to work around it, but you'd have to do a lot to counter-act the default styles employed when clicking.
I used quotation marks around "disable" advisedly; this achieves the thing that many people actually want to accomplish when they google "disable a button". There are 500 upvotes here already for disabled proper, but I thought the approach that doesn't also disable hover text and confuse the user should be listed since it is in many ways a better practice.
-2

its simple let us assume you have made an state full class by extending Component which contains following

class DisableButton extends Components 
   {

      constructor()
       {
         super();
         // now set the initial state of button enable and disable to be false
          this.state = {isEnable: false }
       }

  // this function checks the length and make button to be enable by updating the state
     handleButtonEnable(event)
       {
         const value = this.target.value;
         if(value.length > 0 )
        {
          // set the state of isEnable to be true to make the button to be enable
          this.setState({isEnable : true})
        }


       }

      // in render you having button and input 
     render() 
       {
          return (
             <div>
                <input
                   placeholder={"ANY_PLACEHOLDER"}
                   onChange={this.handleChangePassword}

                  />

               <button 
               onClick ={this.someFunction}
               disabled = {this.state.isEnable} 
              /> 

             <div/>
            )

       }

   }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.