Reactjs setState () z nazwą klucza dynamicznego?

248

EDYCJA: to jest duplikat, patrz tutaj

Nie mogę znaleźć żadnych przykładów użycia nazwy klucza dynamicznego podczas ustawiania stanu. Oto co chcę zrobić:

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

gdzie event.target.id jest używany jako klucz stanu do aktualizacji. Czy to nie jest możliwe w React?

trad
źródło
4
Jest to duplikat każdego pytania dotyczącego dynamicznych kluczy obiektów. Reakcja nie jest specyficzna
Cory Danielson,
9
var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Cory Danielson
Dziękuję, nie miałem dobrego doświadczenia z używaniem obiektów w ogóle.
trad
@trad Mam problem z tym, ale co wprowadziłeś w swój stan początkowy? To nie ma znaczenia, prawda?
Raphael Onofre

Odpowiedzi:

280

Dzięki podpowiedzi @ Cory wykorzystałem to:

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

    this.setState( stateObject );    
},

Jeśli używasz ES6 lub transpilatora Babel do transformacji kodu JSX, możesz to zrobić również za pomocą obliczonych nazw właściwości :

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
źródło
27
Istnieje również nowa składnia, jeśli używasz bablejs do budowania swojego kodu. Możesz użyćcomputed property names
Cory Danielson
Drugie podejście powoduje błąd składniowy w przeglądarkach w systemie Windows (IE, Chrome). Czy ktoś zauważył?
benjaminz
jak się wypowiedzieć?
Muneem Habib,
Dzięki trad, tego właśnie szukałem, aby uniknąć duplikacji kodu do <Radio />implementacji.
Adesh M
6
Jeśli ustawisz stan za pomocą obliczonej nazwy właściwości w ten sposób: w this.setState({ [event.target.id]: event.target.value });jaki sposób uzyskasz dostęp do tego stanu za pomocą this.state......?
user3574492
142

Gdy musisz obsłużyć wiele kontrolowanych elementów wejściowych, możesz dodać atrybut nazwy do każdego elementu i pozwolić funkcji obsługi wybrać, co robić na podstawie wartości event.target.name.

Na przykład:

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

vikram jeet singh
źródło
7
co oznaczają nawiasy wokół [event.target.name]? Dlaczego są wymagane?
user798719,
1
W porównaniu ze zwykłym podejściem do nazywania każdego elementu osobno, takim jak this.setState ({userName: e.target.value}); Będzie to obsługiwać wiele elementów formy jako tablicę i nie trzeba ustawiać poszczególnych elementów
vikram jeet singh
1
ale jak mogę uzyskać dostęp do tego stanu w ten sam sposób? jak this.state([event.target.name])?
Kirankumar Dafda
1
Wydaje mi się, że dokumentacja internetowa MDN i ten post wyjaśniają, dlaczego potrzebujemy nawiasów.
Kelli
46

Jak to osiągnąłem ...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},
sintaxi
źródło
Zrobiłem w podobny sposób, ale problem polegał na tym, że nadal nie renderowałem komponentu, i uruchomiłem kolumnę do postu (w tym to: D), i gdzieś to znalazłem: this.forceUpdate();co nie powinno być w przypadku najnowszej wersji React. Zobaczmy, jaki jest problem później!
xploreraj
24

Chciałem tylko dodać, że możesz również użyć dekstrukturyzacji, aby przefaktoryzować kod i sprawić, by wyglądał ładniej.

inputChangeHandler: function ({ target: { id, value }) {
    this.setState({ [id]: value });
},
kiszone
źródło
10

W pętli z .maptaką pracą:

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

Zwróć uwagę na parametr []in type. Mam nadzieję że to pomoże :)

Johnatan Maciel
źródło
10

Miałem podobny problem.

Chciałem ustawić stan, w którym klucz 2. poziomu był przechowywany w zmiennej.

na przykład this.setState({permissions[perm.code]: e.target.checked})

Nie jest to jednak poprawna składnia.

Aby to osiągnąć, użyłem następującego kodu:

this.setState({
  permissions: {
    ...this.state.permissions,
    [perm.code]: e.target.checked
  }
});
Matthew Holtom
źródło
4

Dzięki ES6 + możesz po prostu zrobić [ ${variable}]

Jujhar Singh
źródło
2

Szukałem ładnego i prostego rozwiązania i znalazłem to:

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

Mam nadzieję że to pomoże

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

Pamiętaj o znaku cytatu.

Javatar
źródło
0

Twój stan ze słownikiem aktualizuje jakiś klucz bez utraty innej wartości

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

Rozwiązanie jest poniżej

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

tutaj zaktualizuj wartość dla klucza „strona” o wartości 5

Manoj Patel
źródło
-4

Może korzystać ze składni spreadu, coś takiego:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},
sta
źródło
7
React zrobi dla ciebie scalenie obiektu, jest to zła praktyka.
Rohmer
1
w zasadzie, jeśli masz jakiś wewnętrzny obiekt i chcesz zmienić jedną właściwość na tym wewnętrznym obiekcie, robisz to w ten sposób: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran Or