本系列文章主要整理於書籍《React狀態管理與同構實戰》,屬於讀書筆記。
本文推薦讀者:菜鳥前端,初學前端者。
本文是系列文章第二篇,主要講述的是如何構建一個簡單的,十分基礎的 Redux,以及每一步大概是做什麼的,希望會對讀者有一丟丟幫助。
複製程式碼
4、 Redux 基本使用和實踐
4.1 構造store
store 儲存著整個狀態資料庫,是 Redux 中核心,裡面儲存許多重要的API。
store = {
dispatch,
getState,
subscribe,
replaceReducer,// 暫時用不到所以暫時忽略
}
複製程式碼
這些方法的使用:
- dispatch(action) : 派發 action
- subscribe(listener): 訂閱頁面資料的狀態, 即 store 中 state 的變化
- getState: 獲取狀態資料樹,即 store 中的 state 狀態
當我們引入 Redux 之後,就可以通過方法 Redux.createStore
建立頁面應用的 store
。
import { createStore } from 'redux';
const store = createStore( reducer, preloadedState, enhancer )
複製程式碼
- reducer: 開發者自己編寫的 reducer 函式,必選
- preloadedState: 頁面狀態資料樹的初始狀態,可選
- ehhancer: 增強器,函式型別,可選
reducer 函式是建立 store 時候必填的引數,所以我們需要在此之前就設計好 reducer 函式,用來告知 store 資料狀態是如何根據 action 進行變更的。
4.2 構造 action
- action 描述了狀態變更的資訊,也就是需要頁面做出的變化。
- action 本質上是一個 JS 物件,根據 Redux 的規定,action 需要包含以下內容:
- type屬性: 作為 action 的名稱,用來識別當前 action ,相當於 action 的身份證(暫時理解為身份證中的國籍,姓名等非單一性的屬性,因為 type 可以是一類物件,而不僅僅只有一個),一般是 string 型別。
- action 的一些資料資訊,主要包括了這個 action 變化的基本內容。
const action = {
type: 'READ_BOOK',
data: {
name: '你不知道的JS'
}
}
// 這裡面的 action.type 可以表述為,’讀書‘。讀的是什麼書? action.data.name:'你不知道的JS'
複製程式碼
4.3 使用 action create (構造器)
存在如下場景:當使用者進行書籍推薦的時候,我們就要生產一個 type: 'READ_BOOK'
的 action,但是這些 action 儘管資料有差別,但是他們的 type 都是一樣的,所以我們可以建立一個函式來構造這些 type 一樣的 action。
const createSameTypeAction = (na'me) => {
type: 'READ_BOOK',
name
}
複製程式碼
4.4 使用 dispatch 派發 action
dispatch 就是 store 物件中暴露出來的方法屬性,可以直接呼叫來派發 action 。
store.dispatch(createSameTypeAction('node.js 實戰'))
複製程式碼
4.5 編寫 reducer 函式更新資料
- action 描述了一種變化,並且攜帶了這種變化的一些相關資訊,而真正將這種變化落實,生成正確的資料狀態的,是 reducer 函式。
- reducer 函式必須是純函式,目的是保證資料變化的可預測性(可以檢視第三節)
const updateStateTree = (preState={},action) => {
switch(action.type){
case:'case1':
return newState1;
case:'case2':
return newState2
default:
return preState // 當所有action都不匹配時,返回預設的狀態
}
}
複製程式碼
4.6 基本使用小結
- 當通過 Redux 的 createState 方法建立出一個 store 例項後,就可以使用 store.dispatch(action) 來派發一個描述變化的 action 。
- 在執行 store.dispatch 之後, Redux 會‘自動’執行處理 store 並更新資料的 reducer 函式。
- 具體的資料變化物件 action 和資料處理函式 reducer 需要開發人員根據具體業務進行編寫。
- reducer 函式處理結束後,資料發生了改變,此時頁面通過 store.subscribe(callbackFunction)方法訂閱資料的更新,根據給定的回撥函式 callbackFunction 進行頁面的更新。
4.7 合理拆分 reducer 函式
當業務變複雜時,可能需要很多 action 來描述不同的變化,此時如果仍然使用一般的 reducer 函式,就會顯得很大而且難以維護,所以 Redux 提供了一個 conbineReducers 的工具函式,用來對拆分 reducer 函式重新合併成一個完整的 reducer。
// 當一個業務需要更改多個資料時,可以根據資料狀態進行拆分
state = {
data1:{...},
data2:{...},
data3:{...},
};
const reducer1 = ( preState={}, action ){
// 根據 action 和 state.data1 計算出新的 state.data1
return state1.data1
};
const reducer2 = ( preState={}, action ){
// 根據 action 和 state.data2 計算出新的 state.data2
return state1.data2
};
const reducer3 = ( preState={}, action ){
// 根據 action 和 state.data3 計算出新的 state.data3
return state1.data3
}
const { combineReducers } = Redux
const finalReducer = combineReducers({
data1: reducer1,
data2: reducer2,
data3: reducer3,
})
複製程式碼