Advertencia: Un componente está cambiando una entrada no controlada de texto de tipo para ser controlada. 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. *

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>
  )
}
313
Riya Kapuria 30 oct. 2017 a las 12:47

7 respuestas

La mejor respuesta

La razón 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á sin control.

Una vez que ingrese cualquier valor en la entrada, fields en el estado cambia a:

this.state = { fields: {name: 'xyz'} }

Y en ese momento el campo de entrada se convierte en un componente controlado; es por eso que obtienes el error:

Un componente está cambiando una entrada no controlada de texto de tipo a controlar.

Soluciones posibles:

1- Defina el fields en estado como:

this.state = { fields: {name: ''} }

2- O defina la propiedad de valor utilizando Evaluación de cortocircuito como esta:

value={this.state.fields.name || ''}   // (undefined || '') = ''
508
Bondolin 22 oct. 2019 a las 18:56

Cambiar value a defaultValue lo resolverá.

Nota :

defaultValue es solo para la carga inicial. Si desea inicializar input, debe usar defaultValue, pero si desea usar state para cambiar el valor, debe usar value. Lea esto para obtener más información.

Usé value={this.state.input ||""} en input para deshacerme de esa advertencia.

23
blueseal 14 nov. 2019 a las 20:25

Además de la respuesta aceptada, si está utilizando un input del tipo checkbox o radio, he descubierto que necesito anular / indefinir verificar el atributo checked también.

<input
  id={myId}
  name={myName}
  type="checkbox" // or "radio"
  value={myStateValue || ''}
  checked={someBoolean ? someBoolean : ''}
  />
6
Lynden Noye 18 ene. 2020 a las 08:53

Establecer estado actual primero ...this.state

Es porque cuando va a asignar un nuevo estado puede ser indefinido. por lo que se solucionará configurando el estado extrayendo el estado actual también

this.setState({...this.state, field})

Si hay un objeto en su estado, debe establecer el estado de la siguiente manera, supongamos que tiene que establecer el nombre de usuario dentro del objeto de usuario.

this.setState({user:{...this.state.user, ['username']: username}})
7
NuOne 5 may. 2019 a las 22:40

SIMPLEMENTE, primero debe configurar el estado inicial

Si no configura estado inicial , reaccionar lo tratará como un componente no controlado

8
Vaibhav Bacchav 15 sep. 2019 a las 17:33
const [name, setName] = useState()

Genera un error tan pronto como escribe en el campo de texto

const [name, setName] = useState('') // <-- by putting in quotes 

Solucionará el problema en este ejemplo de cadena.

5
Nelles 9 feb. 2020 a las 22:03

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"
              />
11
Tabish 12 nov. 2019 a las 09:39