2015-12-03 104 views
0

如果我從外部源拉起一些數據到初始狀態,然後想添加其他信息,例如'喜歡'? 我已經嘗試添加到產品數組,但它走得凌亂,我想我應該有一個額外的數組喜歡的項目,然後把產品ID在這個,唯一的事情是我需要它反映在產品中它已被喜歡,我正在將產品數據映射到該項目。減速器:添加到陣列數據

最好的方法是什麼?

const initialState = { 
    isFetching: false, 
    products: [], 
}; 

我應該加上favs:[]?

當我將產品數組映射到產品組件時,我如何將我喜歡的狀態反映到我的產品中?而喜歡的國家現在處於收益狀態?

我試着這樣做,將其添加到產品陣列,但它得到了真正凌亂(像這樣)

case ADD_LIKED: 
state.products[action.index]['liked'] = true; 
return state; 
+0

reducer它是_pure_函數。你應該用現有的數組加上新的數據返回新的狀態 –

+0

是的,我知道它是錯誤的,它更多的是表達我想要達到的目標。 – user3224271

回答

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