#javascript #reactjs #object #react-hooks #use-state
Вопрос:
Я пытаюсь выполнить функцию заданного состояния и изменить только одно значение.
Это объект, и, например, я хочу изменить book1 в индексе [0] (так что имя 1) с true на false.
Я не могу понять, как это сделать
все, что я пытаюсь, просто перезаписывает часть объекта
{
book1: [
{ name: 1, selected: true },
{ name: 2, selected: false },
{ name: 3, selected: false },
{ name: 4, selected: false },
{ name: 5, selected: true },
],
book2: [
{ name: 1, selected: false },
{ name: 2, selected: false },
{ name: 3, selected: true },
{ name: 4, selected: false },
{ name: 5, selected: true },
],
}
Комментарии:
1. не по теме, но взгляните на immerjs . Это может облегчить вашу жизнь.
Ответ №1:
Поскольку объект находится в состоянии, вы не можете изменить его напрямую. Вместо этого вам нужно создать копию объекта и любых внутренних объектов (включая массивы), которые вы изменяете. См. Комментарии:
// Use the callback form because you're updating state based on existing state
setTheObject(original => {
// Shallow copy the object and book1
const update = {...original, book1: [...original.book1]};
// Replace the object at index 0 with a new updated object
update.book1[0] = {...update.book1[0], selected: false};
// return the update
return update;
});
Технически это возможно сделать за одну вложенную операцию, но ее гораздо сложнее читать и отлаживать:
// Use the callback form because you're updating state based on existing state
setTheObject(original => ({
// Shallow copy the object
...original,
// Shallow copy `book1` while updating index 0 with a copy of the object with the updated property
book1: Object.assign([], original.book1, {0: {...original.book1[0], selected: false}}),
}));
Я не рекомендую этого делать. 😀
Ответ №2:
const [books, setBooks] = useState({
book1: [
{ name: 1, selected: true },
{ name: 2, selected: false },
{ name: 3, selected: false },
{ name: 4, selected: false },
{ name: 5, selected: true }
],
book2: [
{ name: 1, selected: false },
{ name: 2, selected: false },
{ name: 3, selected: true },
{ name: 4, selected: false },
{ name: 5, selected: true }
]
});
Предположим, вы держите книги в таком состоянии. Теперь обновите состояние книг следующим образом.
setBooks({
...books,
book1: books.book1.map((book) =>
book.name === 1 ? { ...book, selected: !book.selected } : book
)
});
Чтобы проверить эффект после изменения состояния, вы можете добавить зависимость в крючок useEffect, и как только книги будут изменены, вы увидите обновленное состояние в useEffect.
useEffect(() => {
console.log(books);
}, [books]);