Tengo este componente:
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>
);
}
}
Quiero que el botón esté desactivado cuando el valor de entrada esté vacío. Pero el código anterior no funciona. Dice:
add-item.component.js: 78 Uncaught TypeError: No se puede leer la propiedad 'valor' de indefinido
señalando disabled={!this.input.value}
. ¿Qué puedo estar haciendo mal aquí? Supongo que tal vez ref aún no se crea cuando render
se ejecuta el método. Si, entonces, ¿cuál es la solución alternativa?
fuente
disabled
atributo del DOM si está configurado enfalse
; esto es compatible con todos los navegadores.En HTML,
Todos ellos se reducen a disabled = "true", eso se debe a que devuelve true para una cadena no vacía. Por lo tanto, para devolver falso, pase una cadena vacía en una declaración condicional como 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> ); }
fuente
No debería establecer el valor de la entrada a través de refs.
Eche un vistazo a la documentación de los componentes de formularios controlados aquí: https://facebook.github.io/react/docs/forms.html#controlled-components
En una palabra
<input value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} />
Entonces podrá controlar el estado deshabilitado usando
disabled={!this.state.value}
fuente
Hay algunos métodos típicos de cómo controlamos la representación de componentes en React.
Pero, no he usado ninguno de estos aquí, solo usé las referencias para el espacio de nombres subyacente a los niños del componente.
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>
fuente
this.input
no está definido hasta queref
se llame a la devolución de llamada. Intente establecerthis.input
un valor inicial en su constructor.De los documentos de React sobre referencias , el énfasis es mío:
fuente
He tenido un problema similar, resulta que no necesitamos ganchos para hacer esto, podemos hacer un render condicional y seguirá funcionando bien.
<Button type="submit" disabled={ name === "" || email === "" || password === "" ? true : false } fullWidth variant="contained" color="primary" className={classes.submit}> SignUP </Button>
fuente
solo agrega:
<button disabled={this.input.value?"true":""} className="add-item__button" onClick={this.add.bind(this)}>Add</button>
fuente
Una solución muy simple para esto es usar
useRef
hookconst 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>
Del mismo modo, puede habilitar el botón utilizando
buttonRef.current.disabled = false
fuente