Reactjs setState () con un nome chiave dinamico?


248

EDIT: questo è un duplicato, vedi qui

Non riesco a trovare alcun esempio di utilizzo di un nome chiave dinamico quando si imposta lo stato. Questo è quello che voglio fare:

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

dove event.target.id viene utilizzato come chiave di stato da aggiornare. Questo non è possibile in React?


4
Questo è un duplicato di qualsiasi domanda relativa alle chiavi dinamiche degli oggetti. Non è specifico per reagire
Cory Danielson,

9
var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Cory Danielson,

Grazie, non avevo una buona padronanza sull'uso degli oggetti in generale.
trad


@trad Sono con questo problema ma, cosa hai messo nel tuo stato iniziale? Non importa, vero?
Raphael Onofre,

Risposte:


280

Grazie al suggerimento di @ Cory, ho usato questo:

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

    this.setState( stateObject );    
},

Se usi ES6 o il transpiler Babel per trasformare il tuo codice JSX, puoi farlo anche con nomi di proprietà calcolati :

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
C'è anche una nuova sintassi per questo, se stai usando bablejs per costruire il tuo codice. Puoi usarecomputed property names
Cory Danielson il

Il secondo approccio provoca errori di sintassi nei browser su Windows (IE, Chrome). Qualcuno l'ha notato?
Benjaminz,

come farsi dichiarare?
Muneem Habib,

Grazie trad, questo è quello che stavo cercando per evitare la duplicazione del codice per l' <Radio />implementazione.
Adesh M

6
Se imposti uno stato utilizzando il nome della proprietà calcolata in questo modo: this.setState({ [event.target.id]: event.target.value });come accederesti a tale stato this.state......?
user3574492

142

Quando è necessario gestire più elementi di input controllati, è possibile aggiungere un attributo name a ciascun elemento e lasciare che la funzione handler scelga cosa fare in base al valore di event.target.name.

Per esempio:

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


7
cosa indicano le parentesi intorno a [event.target.name]? Perché sono richiesti?
user798719

1
Rispetto al solito approccio per nominare ciascun elemento separatamente come this.setState ({userName: e.target.value}); Questo gestirà più elementi del modulo come un array e non è necessario impostare ogni singolo elemento
vikram jeet singh

1
ma come posso accedere a quello stato allo stesso modo? come this.state([event.target.name])?
Kirankumar Dafda,

1
Penso che i documenti web MDN e questo post spieghino perché abbiamo bisogno delle parentesi.
Kelli

46

Come ho realizzato questo ...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},

Ho fatto lo stesso modo, ma il problema era che non rendevo ancora il componente e ho eseguito il pilastro per pubblicare (incluso questo: D), e da qualche parte this.forceUpdate();ho trovato questo: che non avrebbe dovuto essere il caso dell'ultimo React. Vediamo qual è il problema più tardi !!
xploreraj,

24

Volevo solo aggiungere che puoi anche usare la destrutturazione per riformattare il codice e renderlo più ordinato.

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

10

In loop con .maplavoro come questo:

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

Si noti la []di typeparametro. Spero che questo ti aiuti :)


10

Ho avuto un problema simile.

Volevo impostare lo stato in cui era memorizzata la chiave di 2 ° livello in una variabile.

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

Tuttavia questa non è sintassi valida.

Ho usato il seguente codice per raggiungere questo obiettivo:

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


2

Stavo cercando una soluzione carina e semplice e ho trovato questo:

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

Spero che questo ti aiuti


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

Si prega di tenere presente il carattere di citazione.


0

Il tuo stato con dizionario aggiorna alcune chiavi senza perdere altro valore

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

La soluzione è sotto

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

qui aggiorna il valore per la chiave "pagina" con il valore 5


-4

Può usare una sintassi diffusa, qualcosa del genere:

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

7
React farà l'oggetto fondendosi per te, questa è una cattiva pratica.
Rohmer,

1
fondamentalmente se hai qualche oggetto interno e vuoi cambiarne uno proprio su quell'oggetto interno, lo fai in questo modo: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran Or
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.