Tengo un componente de reacción simple con la forma 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, aparece la siguiente advertencia:
Advertencia: MyForm está cambiando una entrada no controlada de texto de tipo para controlar. Los elementos de entrada no deben cambiar de no controlado a controlado (o viceversa). Decida entre usar un elemento de entrada controlado o no controlado durante la vida útil del componente
Creo que mi entrada está controlada ya que tiene un valor. Me pregunto qué estoy haciendo mal.
Estoy usando React 15.1.0
fuente
name={'question_groups.${questionItem.id}'}
?value
accesorio tiene un valor no nulo / indefinido. El accesorio no necesita corresponder a una variable de estado (podría ser una constante y el componente aún se consideraría controlado). La respuesta de Adán es más correcta y debe ser aceptada.Cuando renderiza su componente por primera vez,
this.state.name
no está configurado, por lo que se evalúa enundefined
onull
, y termina pasandovalue={undefined}
ovalue={null}
a suinput
.Cuando los cheques ReactDOM a ver si un campo se controla, comprueba para ver si
value != null
(nota que es!=
, no!==
), y puesto queundefined == null
en JavaScript, se decide que no se la controla.Entonces, cuando
onFieldChange()
se llama,this.state.name
se establece en un valor de cadena, su entrada pasa de no ser controlada a ser controlada.Si lo hace
this.state = {name: ''}
en su constructor, porque'' != null
su entrada tendrá un valor todo el tiempo, y ese mensaje desaparecerá.fuente
this.props.<whatever>
, que fue el problema de mi parte. Gracias Adam!render()
o una expresión en la propia etiqueta, cualquier cosa que se evalúeundefined
. Me alegro de poder ayudar!name
".undefined
inicialmente se pase un valor de . Más bien, es el hecho de quethis.state.name
no existe como una variable de estado lo que hace que la entrada no esté controlada. Por ejemplo, tenerthis.state = { name: undefined };
resultaría en el control de la entrada. Debe entenderse que lo que importa es de dónde proviene el valor, no cuál es el valor.this.state = { name: undefined }
todavía resultaría en una entrada no controlada.<input value={this.state.name} />
desugars aReact.createElement('input', {value: this.state.name})
. Debido a que el acceso a una propiedad inexistente de un objeto devuelveundefined
, esto se evalúa exactamente a la mismaReact.createElement('input', {value: undefined})
llamada a la función, yaname
sea que no esté establecido o establecido explícitamenteundefined
, entonces React se comporta de la misma manera. Puede ver este comportamiento en este JSFiddle.Otro enfoque podría ser establecer el valor predeterminado dentro de su entrada, como este:
fuente
Sé que otros ya han respondido esto. Pero un factor muy importante aquí que puede ayudar a otras personas que experimentan un problema similar:
Debe tener un
onChange
controlador agregado en su campo de entrada (por ejemplo, textField, casilla de verificación, radio, etc.). Maneje siempre la actividad a través delonChange
controlador.Ejemplo:
Cuando trabaje con la casilla de verificación, es posible que deba controlar su
checked
estado!!
.Ejemplo:
fuente
La solución simple para resolver este problema es establecer un valor vacío por defecto:
fuente
Una posible desventaja de establecer el valor del campo en "" (cadena vacía) en el constructor es si el campo es un campo opcional y se deja sin editar. A menos que haga un poco de masaje antes de publicar su formulario, el campo se mantendrá en su almacenamiento de datos como una cadena vacía en lugar de NULL.
Esta alternativa evitará cadenas vacías:
fuente
Cuando use
onChange={this.onFieldChange('name').bind(this)}
en su entrada, debe declarar su cadena vacía de estado como un valor del campo de propiedad.forma incorrecta:
forma correcta:
fuente
En mi caso, me faltaba algo realmente trivial.
<input value={state.myObject.inputValue} />
Mi estado era el siguiente cuando recibí la advertencia:
Al alternar mi estado para hacer referencia a la entrada de mi valor , mi problema se resolvió:
fuente
Si los accesorios de su componente se pasaron como un estado, coloque un valor predeterminado para sus etiquetas de entrada
fuente
Establezca un valor para la propiedad 'nombre' en el estado inicial.
fuente
Una actualización para esto. Para usar React Hooks
const [name, setName] = useState(" ")
fuente
" "
y no""
? Esto hace que pierda cualquier texto de sugerencia, y si hace clic y escribe, obtendrá un espacio furtivo antes de cualquier dato que ingrese.Esto generalmente ocurre solo cuando no está controlando el valor del archivo cuando se inició la aplicación y después de que algún evento o alguna función se activó o el estado cambió, ahora está tratando de controlar el valor en el campo de entrada.
Esta transición de no tener control sobre la entrada y luego tener control sobre ella es lo que hace que el problema ocurra en primer lugar.
La mejor manera de evitar esto es declarando algún valor para la entrada en el constructor del componente. Para que el elemento de entrada tenga valor desde el inicio de la aplicación.
fuente
Para establecer dinámicamente propiedades de estado para entradas de formulario y mantenerlas controladas, puede hacer algo como esto:
fuente
Simplemente cree un respaldo a '' si this.state.name es nulo.
Esto también funciona con las variables useState.
fuente