установка атрибутов внутри объекта объекта с использованием синтаксиса prevState

#reactjs

#reactjs

Вопрос:

Каждый продукт может содержать более одной категории, поэтому я пытаюсь создать объект категорий внутри объекта products, который выглядит следующим образом:

 {
"name":"my product",
"categories":{}
}
  

Все категории отображаются в флажках. Вот как выглядит мое событие изменения флажка:

 const handleChangeCategories = (e, data) => {
    const { name, checked } = data;
    setProductData(prevState => ({
        ...prevState.categories,
        [name]: checked
    }));
};
  

при handleChangeCategories запуске он перезаписывает весь prevState объект вместо добавления объекта в categories .

Ожидаемый результат:

 {
"name":"my product",
"categories:{"cat1":true, "cat2":true}
}
  

Я могу достичь этого с помощью приведенного ниже кода, но он действительно чувствует react , как это делается:

 const handleChangeCategories = (e, data) => {
    const { name, checked } = data;
    let categories = productData.categories
    categories[name] = checked
    setProductData(productData)
};
  

Как мне достичь этого с ...prevState.categories синтаксисом и как мне обрабатывать сценарий, когда категории if не определены, поэтому он должен создать объект categories?

Ответ №1:

Если я понимаю ваш вопрос, вы просто хотите обновить состояние вложенных «категорий» с помощью флажков. Предполагая, что ваше начальное состояние

 {
  name: "my product",
  categories: {},
}
  

Затем ниже показано, как вы будете копировать существующее состояние и вложенное состояние. Вам нужно неглубоко копировать каждый уровень состояния, который обновляется.

 const handleChangeCategories = (e, data) => {
  const { name, checked } = data;
  setProductData(prevState => ({
    ...prevState, // <-- copy root state object
    categories: {
      ...prevState.categories, // <-- copy nested categories
      [name]: checked, // <-- update the specific category
    },
  }));
};
  

Ответ №2:

Перенесите предыдущий .categories объект в новое categories свойство, а не во весь объект, возвращаемый в setProductData :

 setProductData(prevState => ({
    ...prevState, // or: `name: prevState.name`
    categories: {
        ...prevState.categories,
        [name]: checked
    }
}));