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?


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 });
}

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 });
}


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)
},

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 });
},

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 :)


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
  }
});


2

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

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

Espero que esto ayude


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.


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


-4

Puede usar una sintaxis extendida, algo como esto:

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.