Reactjs setState () с именем динамического ключа?

160

EDIT: это дубликат, см. здесь

Я не могу найти примеры использования имени динамического ключа при настройке состояния. Это то, что я хочу сделать:

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

где event.target.id используется в качестве ключа состояния для обновления. Разве это невозможно в реактиве?

  • 3
    Это дубликат любого вопроса о ключах динамического объекта. Это не специально реагировать
  • 7
    var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (NewState);
Показать ещё 3 комментария
Теги:
computed-properties

7 ответов

209

Благодаря подсказке @Cory я использовал это:

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

    this.setState( stateObject );    
},

Если вы используете ES6 или Babel transpiler, чтобы преобразовать код 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 });
}
  • 16
    Для этого также есть новый синтаксис, если вы используете bablejs для сборки своего кода. Вы можете использовать computed property names
  • 0
    Второй подход вызывает синтаксическую ошибку в браузерах в Windows (IE, Chrome). Кто-нибудь заметил?
Показать ещё 6 комментариев
78

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

Например:

inputChangeHandler(event) {
  this.setState({ [event.target.name]: event.target.value });
}
  • 1
    Что обозначают квадратные скобки вокруг [event.target.name]? Зачем они нужны?
  • 1
    По сравнению с обычным подходом именовать каждый элемент отдельно, как this.setState ({userName: e.target.value}); Это будет обрабатывать несколько элементов формы в виде массива, и нет необходимости устанавливать каждый отдельный элемент
Показать ещё 2 комментария
35

Как я это сделал...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},
  • 0
    Я поступил аналогичным образом, но проблема заключалась в том, что он все еще не отображал компонент, и я запустил pillar для публикации (включая эту: D), и где-то нашел это: this.forceUpdate(); что не должно было случиться с последним React. Давайте посмотрим, в чем проблема позже!
9

Просто хотел добавить, что вы можете также де-структурировать, чтобы реорганизовать код и сделать его более аккуратным.

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

В цикле с .map работать так:

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

Обратите внимание на [] в параметре type. Надеюсь это поможет :)

0
inputChangeHandler = (event) => {
    const stateObject = {};
    stateObject[event.target.id] = event.target.value;
    this.setState(stateObject);
};
-2

Можно использовать синтаксис распространения, что-то вроде этого:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},
  • 7
    React сделает объект слияния за вас, это плохая практика.
  • 2
    setState уже объединяет состояние с новым реквизитом
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню