Вы близки, по сути, вам нужен второй объект, расширяющий / видоизменяющий вложенный объект, который вы обновляете.
setObj({...obj, [from]: { ...obj[from], [what]: value} });
Примечание: Вы все еще копируете все целиком объект, то есть каждое неисчислимое свойство, так что это технически столь же эффективно (с точки зрения Big-O), что и то, что у вас уже есть / было. ( Может быть, даже немного меньше, так как сейчас две операции распространения !! )
Можно также утверждать, что теперь оно немного менее читаемо, сейчас сводится к одной строке.
Важным шагом для обновления состояния реакции является чистая парадигма функции всегда возвращать новые ссылки на объекты, что является причиной начального распространения объекта.
Следует также отметить, что не рекомендуется хранить сложные объекты в useState
хуках по этой самой причине , поддержание корректного обновления состояния с помощью глубоко вложенных обновлений - это гораздо больше работы. useReducer
обычно рекомендуется для этих ситуаций. Та же сложность обновления существует, но это более четкий шаблон.
const obj = {
one: {
index: "one",
name: "Number one"
},
two: {
index: "two",
name: "Number two"
}
};
function update(from, what, value) {
return {...obj, [from]: { ...obj[from], [what]: value} };
}
console.log(update('one', 'name', 'Number 1'))