¿Cómo deshabilitar un botón cuando una entrada está vacía?

168

Soy nuevo en React JavaScript. Estoy tratando de deshabilitar un botón cuando un campo de entrada está vacío. ¿Cuál es el mejor enfoque en React para esto?

Estoy haciendo algo como lo siguiente:

<input ref="email"/>

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

¿Es esto correcto?

No es solo la duplicación del atributo dinámico, porque también tengo curiosidad por transferir / verificar los datos de un elemento a otro.

Stepan Suvorov
fuente
3
posible duplicado del atributo dinámico en ReactJS
WiredPrairie

Respuestas:

257

Deberá mantener el valor actual de la entrada en estado (o pasar los cambios en su valor a un padre a través de una función de devolución de llamada , o de lado , o <la solución de administración de estado de su aplicación aquí> de modo que eventualmente se devuelva a su componente como accesorio) para que pueda derivar el accesorio deshabilitado para el botón.

Ejemplo usando estado:

<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>

Jonny Buchanan
fuente
3
Impresionante, el ejemplo corre y todo. Buen ejemplo completo y buena demostración interactiva, SO.
four43
1
Esto no funcionará porque disabled, simplemente estando unido a un elemento, significa que el elemento debe ser deshabilitado. No es un bool. Vea esto: developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/…
Kayote
44
@Kayote eso no es cierto para React. Esas etiquetas no son HTML, son JSX. Y en JSX, si un atributo se asigna falso, se elimina por completo al convertirlo a HTML. ¿Acabas de ignorar el comentario inmediatamente superior al tuyo que dice que funciona perfectamente?
Ben Baron el
2
@BenBaron gracias por la aclaración. No recuerdo dónde / cómo lo usé, sin embargo, tuve algunos problemas. Estoy votando tu comentario para que otros sepan que este método es el correcto basado en la experiencia de las personas.
Kayote
3
@Kayote Gracias y perdón si salí un poco grosero con la última parte del comentario. Fue un día muy largo.
Ben Baron
8

El uso de constantes permite combinar múltiples campos para la verificación:

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>

Gi1ber7
fuente
7

Otra forma de verificar es alinear la función, de modo que la condición se verifique en cada render (cada accesorio y cambio de estado)

const isDisabled = () => 
  // condition check

Esto funciona:

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

pero esto no funcionará:

<button
   type="button"
   disabled={this.isDisabled}
>
  Let Me In
</button>
Marc Sloth Eastman
fuente
-1

es simple, supongamos que ha hecho una clase de estado completo al extender el Componente que contiene los siguientes

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/>
            )

       }

   }
keerthi c
fuente