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

3
如标题所述,我正在尝试更改嵌套在对象数组中的对象的状态。我无法使其工作。我在codesandbox中添加了我的示例。
我正在使用 Material-UI 组件调用 ToggleButton(演示链接: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项目,而不仅仅是为了学习框架而搭建的沙盒,同时我也是一名初级开发者,正在努力学习。我在stackoverflow上进行了搜索,但没有找到任何有用的信息。希望我提供了足够的信息,能得到帮助。
3个回答

1
你的状态和应用程序似乎非常复杂,但更新嵌套数组状态的一般思路是在进行更新的每个级别浅复制状态。使用array::map将Category属性映射到一个新的数组对象引用,当类别匹配时切换IsTrue "selected"属性。
setRecipeObjectState((prevState) => ({
  ...prevState,
  Category: prevState.Category.map((category) =>
    category.category === newCategory // <-- newCategory value from toggled button
      ? {
          ...category,
          IsTrue: !category.IsTrue
        }
      : category
  )
}));

由于您的“selected”计算是selected = {Boolean(item.IsTrue)} ,因此您需要确保您的IsTrue 元素值实际上是可切换的,即只需在数组中存储布尔值。

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
};

Edit changing-state-of-object-nested-in-array-of-objects


非常感谢您的帮助!解释得非常好!我知道我的应用程序看起来很复杂。确实如此。事情有点失控,我需要重构它。我一直想找一个导师来帮助我/分享想法,并帮助我发展更好的开发技能。 - jayseven525

0

您正在改变相同的引用,您需要渲染一个副本,否则组件将不会被渲染(浅比较):

尝试像这样更新状态。

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

setRecipeObjectState(oldState);


0

我没有尝试你的组件,因为它太大了。

更新对象数组中单个对象属性似乎是非常普遍的用例。这里是通常的做法。假设每个对象都有一个唯一标识符id,我们想要切换selected属性:

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>
  );
}

https://codesandbox.io/s/xenodochial-river-9sq6g?file=/src/App.js:0-825


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接