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.