Reactjs setState () з ім'ям динамічного ключа?


248

EDIT: це дублікат, дивіться тут

Я не можу знайти прикладів використання динамічного імені ключа під час встановлення стану. Це те, що я хочу зробити:

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

де event.target.id використовується як стан стану, який потрібно оновити. Чи це неможливо в React?


4
Це дублікат будь-якого питання, що стосується динамічних клавіш об'єкта. На це не конкретно реагувати
Cory Danielson

9
var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Кори Даніельсон

Дякую, у мене взагалі не було добре впоратися з використанням об’єктів.
торг


@trad Я з цією проблемою, але що ти поставив у своєму початковому стані? Не має значення, правда?
Рафаель Онофре

Відповіді:


280

Завдяки підказці @ Cory, я використав це:

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

    this.setState( stateObject );    
},

Якщо ви використовуєте ES6 або транспілер Babel для перетворення коду JSX, ви можете це зробити і з обчисленими іменами властивостей :

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
Для цього також є новий синтаксис, якщо ви використовуєте bablejs для створення коду. Можна скористатисяcomputed property names
Cory Danielson

Другий підхід викликає синтаксичну помилку в браузерах на WIndows (IE, Chrome). Хтось помітив?
Бенджамінц

як отримати заяву?
Muneem Habib

Дякую trad, це те, що я шукав, щоб уникнути дублювання коду для <Radio />реалізації.
Адеш М

6
Якщо ви встановите стан, використовуючи обчислене ім'я властивості, як це: this.setState({ [event.target.id]: event.target.value });то як би ви отримали доступ до цього стану за допомогою this.state......?
користувач3574492

142

Коли вам потрібно обробити кілька керованих вхідних елементів, ви можете додати атрибут імені до кожного елемента та дозволити функції обробника вибрати, що робити, виходячи зі значення event.target.name.

Наприклад:

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


7
про що вказують дужки навколо [event.target.name]? Чому вони потрібні?
користувач798719

1
У порівнянні зі звичайним підходом до назви кожного елемента окремо, як this.setState ({userName: e.target.value}); Це буде обробляти декілька елементів форми як масив і не потрібно встановлювати кожен окремий елемент
vikram jeet singh

1
але як я можу отримати доступ до цього стану таким же чином? як this.state([event.target.name])?
Кіранкумар Дафда

1
Я думаю, що веб-документи MDN і цей пост пояснює, для чого нам потрібні дужки.
Келлі

46

Як я це досяг ...

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

Я зробив подібний шлях, але проблема полягає в тому, що він все ще не виводив компонент, і я побіг на стовп для публікації (включаючи це: D), і десь виявив це: this.forceUpdate();що не мало бути з останнім React. Давайте подивимось, що питання пізніше !!
xploreraj

24

Я просто хотів додати, що ви також можете використовувати деструктуризацію для рефакторації коду та зробити його виглядом акуратніше.

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

10

У циклі з .mapтакою роботою:

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

Зверніть увагу на параметр []in type. Сподіваюся, це допомагає :)


10

У мене була подібна проблема.

Я хотів встановити стан, де зберігається ключ другого рівня у змінній.

напр this.setState({permissions[perm.code]: e.target.checked})

Однак це невірний синтаксис.

Для цього я використав такий код:

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


2

Я шукав досить просте рішення, і знайшов таке:

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

Сподіваюсь, це допомагає


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

Будь ласка, пам’ятайте про цитату.


0

Ваш стан зі словником оновить деякий ключ, не втрачаючи іншого значення

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

Рішення нижче

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

тут оновіть значення для ключової "сторінки" зі значенням 5


-4

Можливо використовувати синтаксис розповсюдження приблизно так:

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

7
React зробить об'єкт для вас об’єднанням, це погана практика.
Ромер

1
в основному, якщо у вас є якийсь внутрішній об'єкт, і ви хочете змінити один проппер на цьому внутрішньому об'єкті, ви робите це так: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Еран Або
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.