gpt4 book ai didi

javascript - 数组中数组的正确组件树在更改时重新渲染

转载 作者:行者123 更新时间:2023-12-01 02:05:21 24 4
gpt4 key购买 nike

我正在绞尽脑汁试图理解我应该使用的组件结构。我觉得这是我绝对想要正确得到的东西,因为 future 了解 ReactJS 应用程序应该如何以及如何正确分离关注点非常重要。我知道这是一个固执己见的前台,但我目前的做法是不正确的,我正在寻找一些见解。

数据模型:这是一个很大的食谱数组,每个食谱都包含另一个数组的成分。我想允许用户在购买/获取成分时“勾选”(成分从数组中删除)。

[
...
{
"title": "Recipe 1"
"ingredients": [
{ "title": "Flour", "measurement": "300g" },
{ "title": "Sesame Seeds", "measurement": "1 Tblsp" }
]
},
...
]

当前伪组件树:

// RecipeList is my "HOC" (higher-order component) and contains all the functions/data required for the rest of the tree, and simply passes them down as props. This is `connect()`ed to the store here.
<RecipeList>
// Map on the highest level array to display a <Recipe> component for each
<Recipe data={recipe[mappedIndex]}>
// Map on each ingredient to create a list item for each
<RecipeIngredient data={recipe[mappedIndex].ingredient[mappedIndex]>
<IngredientCheckBox onChange={ //remove this ingredient from the array } />
</RecipeIngredient>
</Recipe>
</RecipeList>

以上一切都很好,数据的显示完全符合我的预期。

但是,当涉及 onChange 时,这是主要问题。我调用一个操作,COMPLETE_INGREDIENT这基本上将其从 ingredients 中删除数组(我看到它在运行,使用 redux-logger next-state 不包含它)。

不幸的是,我的组件不会重新渲染。它不再位于数组中,但仍显示在屏幕上。据我了解,这可能是以下原因之一:

  • connect()仅浅层比较状态,因此不会触发重新渲染,因为它是数组中的值,位于数组中对象的属性内部。
  • 我的connect()离行动太远了,应该重新 connect()在更深的组件级别进行编辑,例如 <Recipe>组件,并且仅将其附加到它关心的商店的一部分(甚至可能是 <RecipeIngredient> )。
  • 我的 reducer 没有以不可变的方式修改状态。这是我花费最多时间的一个,但是即使使用 slice()诸如此类,我仍然无法重新渲染

编辑:我的操作 reducer COMPLETE_INGREDIENT 。我知道这可能是问题所在,因为它直接改变了状态。对国家进行如此深刻的变革,正确的做法是什么?

case COMPLETE_INGREDIENT:
// state is from a level above the recipe's, that contains a timestamp etc
state.recipes[action.payload.recipeIndex].ingredients.splice(action.payload.ingredientIndex, 1)

return Object.assign({
...state
})

最佳答案

Edit: My reducer for action COMPLETE_INGREDIENT. I understand this may be the issue, as it is directly mutating the state. What would be the correct way for such a deep change to the state?

是的,您正在使用该 Object.assign 改变状态。作为第一个参数,它应该有新的对象来复制值并返回:

return Object.assign({}, {
...state
})

根据您的代码,我创建了我可能会创建的更新功能:

case COMPLETE_INGREDIENT: {
const { recipeIndex, ingregientIndex } = action.payload;
const recipesListCopy = [...state.recipes];
const recipeCopy = {
...recipesListCopy[recipeIndex],
ingredients: recipesListCopy[recipeIndex].ingredients.filter(
(e, index) => index !== ingredientIndex
)
};
recipesListCopy[recipeIndex] = recipeCopy;
return {
...state,
recipes: recipesListCopy
};
}

编辑:

根据您的评论 - “如果成分数组现在为空,则从顶级配方数组中删除配方”

case COMPLETE_INGREDIENT: {
const { recipeIndex, ingregientIndex } = action.payload;
const recipesListCopy = [...state.recipes];
const updatedIngredientsList = recipesListCopy[recipeIndex].ingredients.filter(
(e, index) => index !== ingredientIndex
);

if(updatedIngredientsList.length > 0) {
// update ingredients
const recipeCopy = {
...recipesListCopy[recipeIndex],
ingredients: updatedIngredientsList
};
recipesListCopy[recipeIndex] = recipeCopy;
} else {
// remove recipe because no igridients
recipesListCopy.splice(recipeIndex, 1);
}

return {
...state,
recipes: recipesListCopy
};
}

关于javascript - 数组中数组的正确组件树在更改时重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50150329/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com