Привет, ребята, я пытаюсь обновить состояние вложенного объекта в React, сейчас я делаю это:
handleChangeEvent({target: {id, value}}, type) {
this.setState(
state => ({
dwelling: (Object.assign(state.dwelling, {[id]: {[type]: value}}))
})
);
}
это происходит из группы форм:
<FormGroup controlId = "spaces">
<ControlLabel>Dormitorios</ControlLabel>
<FormControl
componentClass = "select"
value = {dwelling.spaces.dorms}
placeholder = "Seleccione"
onChange = {e => this.handleChangeEvent(e, 'dorms')}
>
Проблема в том, что когда я обновляю состояние подобъекта, создается dwelling.spaces.dorms, но когда я пытаюсь разместить другое свойство, оно заменяет старое, а не добавляется:
До Dwelling:
{
address: "",
currency: "",
price: 0,
publicationType: "",
spaces: {
closets: "",
dorms: "",
pools: ""
},
subtype: "",
type: ""
}
После onChange для dwelling.spaces.dorms
{
address: "",
currency: "",
price: 0,
publicationType: "",
spaces: {
dorms: "3",
},
subtype: "",
type: ""
}
После onChange для dwelling.spaces.closets
{
address: "",
currency: "",
price: 0,
publicationType: "",
spaces: {
closets: "3",
},
subtype: "",
type: ""
}





В этом примере для сохранения ваших старых свойств используется оператор распространения ES6, который является эквивалентом Object.assign.
Итак, вы не сохраняете вложенное значение.
this.setState({
dwelling: {
...this.state.dwelling,
[id]: {
...this.state.dwelling[id],
[type]: value
}
}
});
В вашем примере вы заменили свое значение новым объектом. Обратите внимание на выделенный жирным шрифтом текст ниже.
dwelling: (Object.assign(state.dwelling, {[id]: {[type]: value}}))
В тексте, выделенном жирным шрифтом, он специально устанавливает новый объект в state.dwelling без сохранения старых значений. Итак, что мы сделали, так это то, что мы использовали оператор распространения ES6, чтобы помочь объединить ваши старые значения с новым значением.
{
...this.state.dwelling[id],
[type]: value
}
Что случилось, вам нужно также использовать Object.assign во вложенном значении Object.assign(state.dwelling, {[id]: Object.assign(state.dwelling[id], {[type]: value}) })
Вы перезаписывали свой [id] новым значением, и ваше новое значение никогда не получало старые реквизиты, поэтому вам нужно было использовать либо распространение, либо Object.assign во вложенном значении
не могли бы вы объяснить, что сделал ваш код, чтобы явить ваше решение, пожалуйста
спасибо за точность @KennethTruong, если я хорошо понимаю, в первой последовательности в вашем первом примере, в setState, dwelling: { ...this.state.dwelling, [id] эквивалентен this.state.dwelling.id
О нет! Если вы прочитали о распространении ES6, оператор ...this.state.dwelling скопирует за вас весь объект. При этом все находящиеся за ним свойства будут объединены. Итак, {...this.state.dwelling } - это то же самое, что и жилье. (За исключением того, что он создает новый объект)
Я сохраняю состояние формы в сложном объекте и для упрощения кода использую эту вспомогательную функцию в моей функции handleChangeEvent, на которую ссылаются TextField, Select и т. д.
export function updateObject(obj, keys, value) {
let key = keys.shift();
if (keys.length > 0) {
let tmp = updateObject(obj[key], keys, value);
return {...obj, [key]: tmp};
} else {
return {...obj, [key]: value};
}
}
Пример React-redux / Material-UI
let [formState, changeFormState] = useState({});
function handleChangeEvent(event) {
changeFormState(updateObject(formState, event.target.name.split('.'),
event.target.value));
}
<TextField className = {classes.textfield} name='foo.bar' value=
formstate.foo.bar || ''} onChange = {handleChangeEvent} />
Я работал отлично, я добавил
state =>, чтобы он оставался работоспособным. что происходило на последнем?