Un componente está cambiando una entrada no controlada de tipo texto para controlar el error en ReactJS
Advertencia: Un componente está cambiando una entrada no controlada de tipo texto para controlarla. Los elementos de entrada no deben pasar de no controlados a controlados (o viceversa). Decida entre utilizar un elemento de entrada controlado o no controlado durante la vida útil del componente.*
El siguiente es mi código:
constructor(props) {
super(props);
this.state = {
fields: {},
errors: {}
}
this.onSubmit = this.onSubmit.bind(this);
}
....
onChange(field, e){
let fields = this.state.fields;
fields[field] = e.target.value;
this.setState({fields});
}
....
render() {
return(
<div className="form-group">
<input
value={this.state.fields["name"]}
onChange={this.onChange.bind(this, "name")}
className="form-control"
type="text"
refs="name"
placeholder="Name *"
/>
<span style={{color: "red"}}>{this.state.errors["name"]}</span>
</div>
)
}
El motivo es que, en el estado que definiste:
this.state = { fields: {} }
campos como un objeto en blanco, por lo que durante la primera representación this.state.fields.name
será undefined
y el campo de entrada obtendrá su valor como:
value={undefined}
Debido a eso, el campo de entrada quedará descontrolado.
Una vez que ingresa cualquier valor en la entrada, fields
el estado cambia a:
this.state = { fields: {name: 'xyz'} }
Y en ese momento el campo de entrada se convierte en un componente controlado; por eso te sale el error:
Un componente está cambiando una entrada no controlada de tipo texto para que sea controlada.
Soluciones posibles:
1- Defina el fields
estado en como:
this.state = { fields: {name: ''} }
2- O defina la propiedad de valor utilizando una evaluación de cortocircuito como esta:
value={this.state.fields.name || ''} // (undefined || '') = ''
Cambiar value
a defaultValue
lo resolverá.
Nota :
defaultValue
es sólo para la carga inicial. Si desea inicializar elinput
entonces debe usardefaultValue
, pero si desea usarlostate
para cambiar el valor entonces debe usarvalue
. Lea esto para obtener más información.
Solía value={this.state.input ||""}
deshacerme input
de esa advertencia.
Dentro del componente coloque el cuadro de entrada de la siguiente manera.
<input
className="class-name"
type= "text"
id="id-123"
value={ this.state.value || "" }
name="field-name"
placeholder="Enter Name"
/>
Además de la respuesta aceptada, si está utilizando un input
tipo de checkbox
o radio
, descubrí que checked
también necesito verificar el atributo como nulo/indefinido.
<input
id={myId}
name={myName}
type="checkbox" // or "radio"
value={myStateValue || ''}
checked={someBoolean ? someBoolean : false}
/>
Y si está utilizando TS (o Babel), puede utilizar la fusión nula en lugar del operador lógico OR:
value={myStateValue ?? ''}
checked={someBoolean ?? false}