Javascript 更改嵌套在对象数组中的对象的状态

Javascript 更改嵌套在对象数组中的对象的状态,javascript,reactjs,material-ui,react-hooks,Javascript,Reactjs,Material Ui,React Hooks,正如标题中所述,我试图更改嵌套在对象数组中的对象的状态。我就是不能让它工作。我已经添加了一个示例,说明我在一个应用程序中正在尝试做什么 我正在使用一个MaterialUI组件调用ToggleButton(链接到演示)。我想更改状态以切换组中的按钮。我能够让它在create函数中工作,但在update函数中却无法工作 尝试更改数组中对象的值对我来说根本不起作用。下面是一些我尝试过但没有成功的事情。我想更改IsTrue:,以便切换按钮以显示用户选择 setAppetizer(true

正如标题中所述,我试图更改嵌套在对象数组中的对象的状态。我就是不能让它工作。我已经添加了一个示例,说明我在一个应用程序中正在尝试做什么

我正在使用一个MaterialUI组件调用ToggleButton(链接到演示)。我想更改状态以切换组中的按钮。我能够让它在create函数中工作,但在update函数中却无法工作

尝试更改数组中对象的值对我来说根本不起作用。下面是一些我尝试过但没有成功的事情。我想更改
IsTrue:
,以便切换按钮以显示用户选择

        setAppetizer(true);            
        setRecipeObjectState({
            ...recipeObjectState,
            Category: [
                ...recipeObjectState.Category,
                {
                    IsTrue: appetizer,
                    category: "Appetizer",
                },
            ],
        });
这只是将更多按钮添加到我的按钮组

        setAppetizer(true);            
        setRecipeObjectState((prevState) => ({
            ...prevState,
            Category: [
                {
                    IsTrue: appetizer,
                    category: "Appetizer",
                },
            ],
        }));

我现在在这一点上迷路了。我还想声明,这是我的第一个React项目,它不仅仅是学习框架的沙箱,我也是一个jr开发人员,正在努力学习。我的搜索溢出,但没有任何帮助。我希望我已经包含了足够的信息,有人可以提供帮助。

如果要修改同一引用,需要渲染副本,否则组件将无法渲染(浅层比较):

尝试像这样更新状态

const oldState = recipeObjectState;
oldState.Category = [
        {
          IsTrue: appetizer,
          category: "Appetizer"
        }
      ];

setRecipeObjectState(oldState);

我没有尝试你的组件,因为它很大

更新对象数组中的单个对象属性似乎是一个非常常见的用例。下面是你通常是如何做到这一点的。假设
id
是每个对象的唯一标识符,我们要切换
所选的

import React, { useState } from "react";
import "./styles.css";
import faker from "faker";

const array = [];
for (let id = 1; id < 10; id++) {
  array.push({
    id,
    name: faker.name.firstName(),
    age: faker.random.number(100),
    selected: false
  });
}

export default function App() {
  const [list, setList] = useState(array);

  const onClick = (id) => (event) => {
    setList((list) =>
      list.map((item) =>
        item.id === id ? { ...item, selected: !item.selected } : item
      )
    );
  };

  return (
    <div className="App">
      Click on a item:
      <ul>
        {list.map(({ id, name, age, selected }) => (
          <li key={id} onClick={onClick(id)} className="item">
            {name} {age}
            {selected ? " ✅" : null}
          </li>
        ))}
      </ul>
    </div>
  );
}
import React,{useState}来自“React”;
导入“/styles.css”;
从“伪造者”进口伪造者;
常量数组=[];
for(设id=1;id<10;id++){
array.push({
身份证件
name:faker.name.firstName(),
年龄:伪造。随机。数字(100),
所选:false
});
}
导出默认函数App(){
const[list,setList]=useState(数组);
const onClick=(id)=>(事件)=>{
集合列表((列表)=>
list.map((项目)=>
item.id==id?{…item,选中:!item.selected}:item
)
);
};
返回(
单击一个项目:
    {list.map({id,name,age,selected})=>(
  • {name}{age} {已选定?“✅" : 空}
  • ))}
); }

您的状态和应用程序看起来非常复杂,但更新嵌套数组状态时的一般想法是在进行更新的每个级别上粗略复制状态。使用array::map将
类别
属性映射到新的数组对象引用,并在类别匹配时切换所选的
IsTrue
“财产

setRecipeObjectState((prevState) => ({
  ...prevState,
  Category: prevState.Category.map((category) =>
    category.category === newCategory // <-- newCategory value from toggled button
      ? {
          ...category,
          IsTrue: !category.IsTrue
        }
      : category
  )
}));

非常感谢您的帮助!。解释得很好!我知道我的应用程序看起来很复杂。它是。事情有点失控,我需要重构它。我一直想试着给自己找一位导师,帮助我走出/跳出一些想法,帮助我培养更好的发展技能。
const recipeObject = {
  AuthorId: authorId,
  BookAuthor: bookAuthor,
  BookTitle: bookTitle,
  Calories: parseInt(calories),
  Category: [
    {
      IsTrue: false,
      category: "Appetizer"
    },
    {
      IsTrue: false,
      category: "Breakfast"
    },
    {
      IsTrue: false,
      category: "Soup / Salad"
    },
    {
      IsTrue: false,
      category: "Vegetarian"
    },
    {
      IsTrue: true,
      category: "Meat (Beef, Pork, Chicken)"
    },
    {
      IsTrue: false,
      category: "Fish"
    },
    {
      IsTrue: false,
      category: "Dessert"
    }
  ],
  Description: description,
  DurationInMinCook: parseInt(durationInMinCook),
  DurationInMinPrep: parseInt(durationInMinPrep),
  ImageUrl: imageUrl,
  Ingredients: addedIngredients, // array
  Instructions: addedInstructions, // array
  IsRecipe: true,
  Likes: 0,
  RecipeId: selectedRecipeId,
  ServingSize: parseInt(servingSize),
  Title: title,
  YouTubeUrl: youTubeUrl
};