Обновление значений вложенных объектов с помощью записи массива в состоянии реагирования - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть некоторый общий код, который пытается обновить определенные состояния. Доступ к объекту возможен по ключам в массиве, например:

let x = {person: { name: "Dennis"}} 
console.log(x["person"]["name"])

В реакции можно (и часто используется при проверке ввода) получить доступ к определенному ключу состояния по массиву, например:

//event.target.name = input field property name="firstName"
this.setState({
    [event.target.name]: event.target.value
});

Что обновит this.state.firstName до значения ввода.

Я пытаюсь связать вложенные сложные объекты с входными данными, чтобы избежать использования функций перевода. Поэтому, если мое состояние содержит { person: {name : "" } }, я хочу получить к нему динамический доступ через this.state ["person"] ["name"] - что работает. Я хочу использовать ту же запись в setState, потому что тогда я могу привязать свои вложенные данные о состоянии к таким входам: <input name="person.name" /> и в своем обработчике изменений я могу искать периоды: if(ev.target.name.split("."))...

Однако я не могу получить доступ к состоянию таким же образом в setState, потому что это объект, поэтому:

const args = ev.target.name.split(".");
this.setState({
    [args[0]][args[1]]: ev.target.value
});

Есть ли в любом случае, чтобы сделать это?

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Это немного сложнее, вы можете глубоко копировать объекты:

 const args = ev.target.name.split(".");
 let result = {};
 const root = result;
 let pos = this.state;
 const last = args.pop();
 for(const arg of args) {
   Object.assign(result, pos);
   result = result[arg] || (result[arg] = {});
   pos = pos[arg] || {};
 }
 result[last] = evt.target.value;
 this.setState(root);
0 голосов
/ 30 апреля 2018

Оказывается, это было немного сложнее, чем первоначально предполагалось. При использовании Object.assign все вложенные объекты сохраняли свои неизменные свойства, что делало невозможным их изменение. Я должен был сделать печатную копию государства, чтобы изменить это. С помощью _set из lodash.set это может быть сделано в несколько строк:

//Create a hard-copy of the state
let stateCopy = JSON.parse(JSON.stringify(this.state));

//Update the value in the state with the input value
_set(stateCopy, ev.target.name, ev.target.value);

//Set the state with the changed value
this.setState(stateCopy);

Редактировать: Единственным недостатком является то, что в настоящее время я копирую все состояние в setState (), а не только дельта-значения.

0 голосов
/ 30 апреля 2018

Мне нравится использовать ramda для этого. Это будет выглядеть как

this.setState(R.assocPath(args, ev.target.value))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...