簡體   English   中英

為什么我的Redux減速器重構失敗了?

[英]Why does my Redux reducer refactor fail?

這是我正在嘗試做的一個例子:

const setView = state => payload => ({ ...state, view: payload });

const reducers = {
  SET_VIEW: setView
};

export default (state = initialState, action) => reducers[action.type](state)(action.payload);

不幸的是,我收到以下錯誤:

未捕獲的TypeError:reducers [action.type]不是函數

我究竟做錯了什么? reducers是一個具有函數的對象文字。

實際上,這是一個相當模糊的問題。 原因是,根據createStore上的Redux文檔

創建存儲時, Redux會向您的reducer 發送一個虛擬操作 ,以使用初始狀態填充存儲。 您並不打算直接處理虛擬動作。 請記住,如果作為第一個參數賦予它的狀態是未定義的,那么你的reducer應該返回某種初始狀態,並且你們都已經設置好了。

而文檔中提到的這個虛擬動作恰好是這一行的來源

dispatch({ type: ActionTypes.INIT })

這里, ActionTypes.INIT本質上是字符串@@redux/INIT后跟隨機的數字和句點字符串。

因此,當您使用createStore創建存儲時, createStore一個虛擬操作分派給您的reducer, 並且您的reducers對象中不存在該操作類型 ,因此您會收到undefined不是函數的錯誤。 這就是為什么你的減速機總是有一個默認情況。 例如,使用switch語句,您始終將狀態作為默認情況返回:

switch(action.type) {
  …
  default:
    return state;
}

默認情況允許捕獲諸如Redux本身調度的虛擬動作之類的動作。 同樣的原則適用於您的代碼:

export default (state = initialState, action) => reducers[action.type] ? reducers[action.type](state)(action.payload) : state;

這將檢查Reducer對象中是否確實存在reducers 如果是,則調用reducer。 如果沒有,就像在默認情況下一樣,只返回狀態。

@ Li357對於你為什么會收到這個錯誤是正確的。 我想提出一個解決問題的替代方案:

const setView = state => payload => ({ ...state, view: payload });

const reducers = {
  SET_VIEW: setView
};

const noop = state => () => state;

export default (state = initialState, action) => (reducers[action.type] || noop)(state)(action.payload);

這里的技巧是(reducers[action.type] || noop)部分,如果沒有動作類型的已知處理程序,它將使用noop處理程序。 它只是返回當前狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM