[第06堂] Redux

什麼是Redux?

Redux 是一套除了 React 外在其他框架下也可以使用的資料流管理工具,他定義了資料流的規範,彌補了 React 在元件變多後狀態難以控管的問題,並將資料集中管理,讓程式更容易去維護和測試。

  • action:包含更新資料的方式 action type 及更新資料時所用的值 action payload。

export const GET_ProjectInfo = (payload, callback) => { return (dispatch) => { dispatch({ type: "GET_ProjectInfo", payload: payload, callback: callback, }); }; }
  • dispatcher: 一個溝通用的函式,會接收 action 物件,執行 action 要做的事情,並傳遞資料給reducer。

  • middlewares:對應接收到的 action 執行動作

const fetch = store => next => action => { switch (action.type) { case "GET_MeetingInfo": _axios .get(`/meeting?id=${action.payload}`,) .then(response => { if (response.status === 200) { return response.data.data; } }) .catch(err => { if (err.response.status === 401) { localStorage.clear(); window.location.replace('http://localhost:3000/index'); } alert(err.response.data.message); throw new Error(err); }) .then(json => { if (action.callback) { action.callback(json) } return next({ type: 'SAVE_MeetingInfo', payload: json, }); }); break; ...
  • reducer:接收 dispatch 派發的 action,經過對應 action type 更新 state物件。

const initialState = {}; export default (state = initialState, action) => { switch (action.type) { case "SAVE_ProjectInfo": return { ...state, ProjectInfo: action.payload }; case "SAVE_ProjectType": return { ...state, ProjectType: action.payload }; case "SAVE_ProjectTypeAll": return { ...state, ProjectTypeAll: action.payload }; case "SAVE_Project": return { ...state, Project: action.payload }; default: return state; } };
  • store:資料中心,整合所有 Reducer,每個專案只能有一個 store,並且可以透過 dispatcher 來更新 state。

const projectMiddlewares = [pet, thunk]; const store = createStore( reducers, compose( applyMiddleware( ...projectMiddlewares, ) ) );

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  1. 使用者操作畫面觸發事件,發送action
  2. action透過dispatcher傳送至middlewares以及store
  3. middlewares呼叫對應的API,store向reducer調用對應state
  4. middlewares將API回傳的結果透過dispatcher傳送給reducer
  5. reducer更新state的值
  6. store接收到state的值有變動重新渲染元件

Redux-Saga

解決了redux 非同步的問題,並且程式可讀性較佳。

未命名

  1. 使用者操作畫面觸發事件發送至saga
  2. saga呼叫對應的API,並等待API的回傳結果
  3. 將結果透過dispatcher傳送給store
  4. store向reducer調用對應state
  5. reducer更新state的值
  6. store接收到state的值有變動重新渲染元件
import { put, takeLatest, call, all } from "redux-saga/effects"; import { GET_API} from "../services/api"; import { handleError } from "../utils/error"; function* GET_APIEffect({ payload, callback }) { try { const Result = yield call(GET_API, payload); yield put({ type: "SAVE_API", payload: Result }); if (callback) callback(); } catch (error) { yield handleError(error); } }