state.products[action.index]['liked'] = true;
這裏的問題是,你是變異是減速器內的狀態其中一個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;
}
你甚至可以通過局部應用功能獲得幻想。這使您可以在減速器內編寫非常富有表現力的代碼。
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;
}
reducer它是_pure_函數。你應該用現有的數組加上新的數據返回新的狀態 –
是的,我知道它是錯誤的,它更多的是表達我想要達到的目標。 – user3224271