Reaccionar: cambiar una entrada no controlada
Tengo un componente de reacción simple con el formulario que creo que tiene una entrada controlada:
import React from 'react';
export default class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<form className="add-support-staff-form">
<input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
</form>
)
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
}
export default MyForm;
Cuando ejecuto mi aplicación recibo la siguiente advertencia:
Advertencia: MyForm está cambiando una entrada no controlada de tipo texto para que sea controlada. Los elementos de entrada no deben pasar de no controlados a controlados (o viceversa). Decidir entre utilizar un elemento de entrada controlado o no controlado durante la vida útil del componente.
Creo que mi entrada está controlada porque tiene un valor. Me pregunto ¿qué estoy haciendo mal?
Estoy usando reaccionar 15.1.0
Creo que mi entrada está controlada porque tiene un valor.
Para que una entrada sea controlada, su valor debe corresponder al de una variable de estado.
Esa condición no se cumple inicialmente en su ejemplo porque this.state.name
no está establecida inicialmente. Por lo tanto, la entrada inicialmente no está controlada. Una vez que el onChange
controlador se activa por primera vez, this.state.name
se configura. En ese punto, se cumple la condición anterior y la entrada se considera controlada. Esta transición de no controlado a controlado produce el error visto arriba.
Inicializando this.state.name
en el constructor:
p.ej
this.state = { name: '' };
la entrada será controlada desde el principio, solucionando el problema. Consulte Componentes controlados de React para obtener más ejemplos.
Sin relación con este error, solo debería tener una exportación predeterminada. Su código anterior tiene dos.
Cuando renderiza su componente por primera vez, this.state.name
no está configurado, por lo que se evalúa como undefined
o null
y termina pasando value={undefined}
o value={null}
a su input
.
Cuando ReactDOM verifica si un campo está controlado, verifica sivalue != null
(tenga en cuenta que es !=
, no !==
), y como undefined == null
en JavaScript, decide que no está controlado.
Entonces, cuando onFieldChange()
se llama, this.state.name
se establece en un valor de cadena, su entrada pasa de estar no controlada a estar controlada.
Si lo hace this.state = {name: ''}
en su constructor, porque '' != null
, su entrada tendrá un valor todo el tiempo y ese mensaje desaparecerá.
Otro enfoque podría ser establecer el valor predeterminado dentro de su entrada, así:
<input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>