Reactjs setState () con un nombre de clave dinámica?

248

EDITAR: este es un duplicado, mira aquí

No puedo encontrar ningún ejemplo del uso de un nombre de clave dinámica al configurar el estado. Esto es lo que quiero hacer:

inputChangeHandler : function (event) {
    this.setState( { event.target.id  : event.target.value } );
},

donde event.target.id se usa como clave de estado para actualizar. ¿No es esto posible en React?

trad
fuente
44
Este es un duplicado de cualquier pregunta relacionada con las claves de objetos dinámicos. No es específico reaccionar
Cory Danielson
99
var estado nuevo = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Cory Danielson
Gracias, no tenía un buen manejo del uso de objetos en general.
Trad
@trad Estoy con este problema pero, ¿qué pusiste en tu estado inicial? No importa, ¿verdad?
Raphael Onofre

Respuestas:

280

Gracias a la pista de @ Cory, usé esto:

inputChangeHandler : function (event) {
    var stateObject = function() {
      returnObj = {};
      returnObj[this.target.id] = this.target.value;
         return returnObj;
    }.bind(event)();

    this.setState( stateObject );    
},

Si usa ES6 o el transpilador de Babel para transformar su código JSX, también puede lograr esto con nombres de propiedades calculados :

inputChangeHandler : function (event) {
    this.setState({ [event.target.id]: event.target.value });
    // alternatively using template strings for strings
    // this.setState({ [`key${event.target.id}`]: event.target.value });
}
trad
fuente
27
También hay una nueva sintaxis para esto, si está utilizando bablejs para construir su código. Puedes usarcomputed property names
Cory Danielson
El segundo enfoque causa un error de sintaxis en los navegadores en Windows (IE, Chrome). ¿Alguien se dio cuenta?
benjaminz
¿Cómo ser declarado?
Muneem Habib
Gracias trad, esto es lo que estaba buscando para evitar la duplicación de código para la <Radio />implementación.
Adesh M
66
Si establece un estado utilizando el nombre de la propiedad calculada de esta manera: this.setState({ [event.target.id]: event.target.value });¿cómo accedería a ese estado utilizando this.state......?
user3574492
142

Cuando necesite manejar múltiples elementos de entrada controlados, puede agregar un atributo de nombre a cada elemento y dejar que la función del controlador elija qué hacer en función del valor de event.target.name.

Por ejemplo:

inputChangeHandler(event) {
  this.setState({ [event.target.name]: event.target.value });
}

vikram jeet singh
fuente
77
¿Qué indican los corchetes alrededor de [event.target.name]? ¿Por qué se requieren?
user798719
1
En comparación con el enfoque habitual para nombrar cada elemento por separado como este.setState ({userName: e.target.value}); Esto manejará múltiples elementos de forma como una matriz y no es necesario configurar cada elemento individual
vikram jeet singh
1
pero aún así, ¿cómo accedo a ese estado de la misma manera? como this.state([event.target.name])?
Kirankumar Dafda
1
Creo que los documentos web de MDN y esta publicación explican por qué necesitamos los corchetes.
Kelli
46

Cómo logré esto ...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},
sintaxi
fuente
Lo hice de manera similar, pero el problema era que todavía no representaba el componente, y ejecuté un pilar para publicar (incluido esto: D), y en algún lugar encontré esto: this.forceUpdate();que no debería haber sido el caso con la última React. ¡Veamos cuál es el problema más tarde!
xploreraj
24

Solo quería agregar, que también puede usar la desestructuración para refactorizar el código y hacer que se vea más ordenado.

inputChangeHandler: function ({ target: { id, value }) {
    this.setState({ [id]: value });
},
saulable
fuente
10

En sintonía con un .maptrabajo como este:

{
    dataForm.map(({ id, placeholder, type }) => {
        return <Input
            value={this.state.type}
            onChangeText={(text) => this.setState({ [type]: text })}
            placeholder={placeholder}
            key={id} />
    })
}

Tenga []en cuenta el typeparámetro in . Espero que esto ayude :)

Johnatan Maciel
fuente
10

Tuve un problema similar.

Quería establecer el estado de dónde se almacenaba la clave de segundo nivel en una variable.

p.ej this.setState({permissions[perm.code]: e.target.checked})

Sin embargo, esta no es una sintaxis válida.

Usé el siguiente código para lograr esto:

this.setState({
  permissions: {
    ...this.state.permissions,
    [perm.code]: e.target.checked
  }
});
Matthew Holtom
fuente
4

Con ES6 + puedes simplemente hacer [ ${variable}]

Jujhar Singh
fuente
2

Estaba buscando una solución bonita y simple y encontré esto:

this.setState({ [`image${i}`]: image })

Espero que esto ayude

Catalina
fuente
1
this.setState({ [`${event.target.id}`]: event.target.value}, () => {
      console.log("State updated: ", JSON.stringify(this.state[event.target.id]));
    });

Por favor, tenga en cuenta el carácter de la cita.

Javatar
fuente
0

Su estado con el diccionario actualiza alguna clave sin perder otro valor

state = 
{   
    name:"mjpatel"  
    parsedFilter:
    {
      page:2,
      perPage:4,
      totalPages: 50,
    }
}

La solución está debajo

 let { parsedFilter } = this.state
 this.setState({
      parsedFilter: {
        ...this.state.parsedFilter,
        page: 5
      }
  });

aquí actualice el valor para la "página" clave con el valor 5

manoj patel
fuente
-4

Puede usar una sintaxis extendida, algo como esto:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},
sta
fuente
77
React hará que el objeto se fusione por ti, esta es una mala práctica.
Rohmer
1
Básicamente, si tiene algún objeto interno y desea cambiar una propiedad en ese objeto interno, lo hace así: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran Or