Redux - 純函式
函式是一個過程,它接收稱為引數的輸入,併產生一些稱為返回值的輸出。如果一個函式遵守以下規則,則稱為純函式:
對於相同的引數,函式返回相同的結果。
它的求值沒有副作用,即它不會更改輸入資料。
不修改區域性和全域性變數。
它不依賴於外部狀態,例如全域性變數。
讓我們以一個函式為例,該函式返回傳遞給函式的輸入值的二倍。通常,它寫成 f(x) => x*2。如果一個函式被呼叫,引數值為 2,則輸出將為 4,f(2) => 4。
讓我們在 JavaScript 中編寫函式的定義,如下所示:
const double = x => x*2; // es6 arrow function console.log(double(2)); // 4
這裡,double 是一個純函式。
根據 Redux 的三個原則,更改必須由純函式(即 Redux 中的 reducer)進行。現在,問題出現了,為什麼 reducer 必須是純函式?
假設您想分派一個型別為 'ADD_TO_CART_SUCCESS' 的 action,透過單擊“新增到購物車”按鈕將商品新增到您的購物車應用程式中。
讓我們假設 reducer 正在將商品新增到您的購物車,如下所示:
const initialState = {
isAddedToCart: false;
}
const addToCartReducer = (state = initialState, action) => { //es6 arrow function
switch (action.type) {
case 'ADD_TO_CART_SUCCESS' :
state.isAddedToCart = !state.isAddedToCart; //original object altered
return state;
default:
return state;
}
}
export default addToCartReducer ;
假設 isAddedToCart 是 state 物件上的一個屬性,它允許您透過返回布林值 “true 或 false” 來決定何時停用商品的“新增到購物車”按鈕。這可以防止使用者多次新增同一產品。現在,我們不是返回一個新物件,而是像上面那樣修改 state 上的 isAddedToCart 屬性。現在,如果我們嘗試將商品新增到購物車,則不會發生任何事情。“新增到購物車”按鈕不會被停用。
這種行為的原因如下:
Redux 透過比較兩個物件的記憶體位置來比較舊物件和新物件。如果發生任何更改,它期望 reducer 返回一個新物件。並且如果沒有任何更改,它也期望獲得舊物件。在這種情況下,它是一樣的。由於這個原因,Redux 假設什麼也沒有發生。
因此,reducer 在 Redux 中必須是純函式是必要的。以下是在不進行修改的情況下編寫它的方法:
const initialState = {
isAddedToCart: false;
}
const addToCartReducer = (state = initialState, action) => { //es6 arrow function
switch (action.type) {
case 'ADD_TO_CART_SUCCESS' :
return {
...state,
isAddedToCart: !state.isAddedToCart
}
default:
return state;
}
}
export default addToCartReducer;