如果我从初始状态的外部源中提取一些数据,那么想要添加其他信息,比如“喜欢”? 我已经尝试添加到产品阵列,但它变得凌乱,我想我应该有一个额外的数组为喜欢的项目然后把产品ID放在这,唯一的是我需要它反映在它有的产品我很喜欢,我正在将产品数据映射到该项目。
最好的办法是什么?
const initialState = {
isFetching: false,
products: [],
};
我应该添加favs:[]?
当我将产品数组映射到产品组件时,我如何将喜欢的状态反映到我的产品中?而喜欢的状态现在在收藏中?
我试着这样做把它添加到产品阵列但是它真的很乱(像这样)
case ADD_LIKED:
state.products[action.index]['liked'] = true;
return state;
答案 0 :(得分:1)
state.products[action.index]['liked'] = true;
这里的问题是你正在改变reducer里面的状态,它是things you should never do inside a reducer之一。
您会发现,如果您将数据分解为较小的部分,那么编写不会改变数据的函数会更容易。例如,您可以开始拆分您的应用程序。
function productsReducer(products = [], action) {
// this reducer only deals with the products part of the state.
switch(action) {
case ADD_LIKED:
// deal with the action
default:
return products;
}
}
function app(state = {}, action) {
return {
isFetching: state.isFetching,
products: productsReducer(state.products, action)
}
}
在这种情况下,我肯定想写一点不变的助手。
function replaceAtIndex(list, index, replacer) {
const replacement = replacer(list[index]);
const itemsBefore = list.slice(0, index),
itemsAfter = list.slice(index + 1);
return [...itemsBefore, replacement, ...itemsAfter];
}
您可以使用用于更改列表中对象的通用函数来补充它。
function updateInList(list, index, props) {
return replaceAtIndex(list, index, item => {
return { ...props, ...item };
});
}
然后你可以用不可变形式重写你的函数
switch(action) {
case ADD_LIKED:
return updateInList(products, action.index, { liked: true });
default:
return products;
}
你可以通过部分应用这个功能来获得幻想。这允许您在reducer中编写非常富有表现力的代码。
const updateProduct = updateInList.bind(this, products, action.index);
switch(action) {
case ADD_LIKED:
return updateProduct({ liked: true });
case REMOVE_LIKED:
return updateProduct({ liked: false });
default:
return products;
}