Dinamik bir anahtar adıyla Reactjs setState ()?


248

EDIT: bu bir kopya, buraya bakın

Durumu ayarlarken dinamik anahtar adı kullanmanın bir örneğini bulamıyorum. Yapmak istediğim şey bu:

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

Burada event.target.id, güncellenecek durum anahtarı olarak kullanılır. React'te bu mümkün değil mi?


4
Bu, dinamik nesne anahtarlarıyla ilgili herhangi bir sorunun kopyasıdır. Tepki vermek spesifik değil
— Cory Danielson

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

Teşekkür ederim, genel olarak nesneleri kullanma konusunda iyi bir fikrim yoktu.
— trad


@trad Bu sorunla ilgiliyim ama, ilk Eyaletinize ne koydunuz? Önemli değil, değil mi?
— Raphael Onofre

Yanıtlar:


280

@ Cory'nin ipucu sayesinde, bunu kullandım:

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

    this.setState( stateObject );    
},

JSX kodunuzu dönüştürmek için ES6 veya Babel aktarıcı kullanıyorsanız , bunu hesaplanan özellik adlarıyla da yapabilirsiniz:

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
Kodunuzu oluşturmak için bablejs kullanıyorsanız, bunun için yeni bir sözdizimi de vardır. Kullanabilirsinizcomputed property names
— Cory Danielson

İkinci yaklaşım, Windows'taki tarayıcılarda (IE, Chrome) sözdizimi hatasına neden olur. Fark eden var mı?
— benjaminz

nasıl ifade edilir?
— Muneem Habib

Teşekkürler trad, bu ben <Radio />uygulama için kod çoğaltma önlemek için aradığını budur .
— Adesh M

6
Hesaplanan özellik adını kullanarak böyle bir durum ayarlarsanız: this.setState({ [event.target.id]: event.target.value });bu durumu kullanarak bu duruma nasıl erişirsiniz this.state......?
— user3574492

142

Birden fazla denetimli giriş öğesini işlemeniz gerektiğinde, her öğeye bir ad niteliği ekleyebilir ve işleyicinin event.target.name değerine göre ne yapılacağını seçmesine izin verebilirsiniz.

Örneğin:

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


7
[event.target.name] etrafındaki köşeli parantezler ne anlama geliyor? Neden gerekli?
— user798719

1
Her öğeyi bu şekilde ayrı ayrı adlandırmak için kullanılan olağan yaklaşımla karşılaştırıldığında ({userName: e.target.value}); Bu, formun birden çok öğesini bir dizi olarak işleyecek ve her bir öğeyi ayarlamanıza gerek olmayacaktır
— vikram jeet singh

1
ama yine de bu duruma nasıl erişebilirim? gibi this.state([event.target.name])mi?
— Kirankumar Dafda

1
Bence MDN web dokümanları ve bu yazı neden parantezlere ihtiyacımız olduğunu açıklıyor.
— Kelli

46

Bunu nasıl başardım ...

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

Benzer şekilde yaptım ama sorun hala bileşeni oluşturmadı ve göndermek için sütun koştum (bu dahil: D) ve bir yerde bunu buldu: this.forceUpdate();son React ile durum böyle olmamalı. Bakalım sorun ne sonra!
— xploreraj

24

Ben sadece kod yeniden düzenleme ve daha temiz görünmesini sağlamak için de-yapılandırmayı kullanabilirsiniz eklemek istedim.

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

10

Böyle bir .mapişte döngü halinde :

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

Not []olarak typeparametresi. Bu yardımcı olur umarım :)


10

Benzer bir sorun yaşadım.

2. seviye anahtarının bir değişkende saklandığı durumu ayarlamak istedim.

Örneğin this.setState({permissions[perm.code]: e.target.checked})

Ancak bu geçerli bir sözdizimi değil.

Bunu başarmak için aşağıdaki kodu kullandım:

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


2

Güzel ve basit bir çözüm arıyordum ve bunu buldum:

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

Bu yardımcı olur umarım


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

Lütfen alıntı karakterine dikkat edin.


0

Sözlükteki durumunuz, başka bir değer kaybetmeden bazı anahtarları günceller

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

Çözüm aşağıda

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

burada "5" anahtarının değerini 5 ile güncelleyin


-4

Yaygın sözdizimini kullanabilir, şuna benzer:

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

7
React sizin için birleştirme nesnesi yapacak, bu kötü bir uygulamadır.
— Rohmer

1
temel olarak bazı iç nesneleriniz varsa ve bu iç nesnenin üzerindeki bir özelliği değiştirmek istiyorsanız bunu şöyle yapabilirsiniz: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
— Eran Veya
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.