iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 13
2
Modern Web

React 30天系列 第 13

Day 13-Redux-Store的三個方法

前情提要:
昨天大致上瞭解了store、reducer和action各自的角色任務,我們今天延續昨天,把action和reducer串連吧!

還記得昨天我們寫好的action嗎?
我們提到了在action設定的type是用來描述state該怎麼改變,
而reducer就是用type來決定怎麼計算下一個state。

在rootReducer的第二個參數action就是由src/actions/index.js送過來的data。

打開我們的src/reducers/index.js
在這,我們依不同的type做不同處理,使用switch語法來匹配不同的type,詳細說明如下:

  1. 匯入常數設定(import action-types)
  2. 使用switch匹配type,目前我們的action只有ADD_ARTICLE。articles的初始值為array,透過array儲存多筆article。
import { ADD_ARTICLE } from "../constants/action-types";  // 1.

const initialState = {
  articles: []
};

const rootReducer = (state = initialState, action) => {
  switch (action.type) {  // 2.
    case ADD_ARTICLE:
      return { ...state, articles: [...state.articles, action.payload] };;
    default:
      return state;
  }
};
export default rootReducer;

注意:array新增的element不能用push method,因為會改變原本的array。如果不想用第三方資源的話可使用concat或spread operator,但object spread operator目前還在stage 3尚未標準化,所以想使用的話最好還是使用babel套件(babel-plugin-transform-object-rest-spread)幫忙轉譯避免產生不必要的SyntaxError。

補充

  1. 避免Redux state變異的方法
    array使用concat(), slice(), and ...spread
    object使用Object.assign() and …spread

  2. 當應用程序(application)越來越大時,reducer也會越來越胖,我們可以藉由把reducer拆分成多個function,然後透過combineReducers把它們結合。

題外話:
我這邊有另外在Pacel安裝babel-plugin-transform-object-rest-spread這個套件,目前babel的版本出到7.x.x但我目前的開發環境只在6.x.x,我除了更新babel版本外,連之前覺得parcel已經做好的preset-env和preset-react一起裝好裝滿,執行步驟如下:

yarn add -D @babel/core @babel/preset-env @babel/preset-react babel-plugin-transform-object-rest-spread

在專案目錄下新增.babelrc檔案

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["transform-object-rest-spread"]
}

Redux store methods

把reducer和action整合之後,我們就可以和瀏覽器的console一起使用藉此快速了解redux的工作原理。
redux是個一個超小函式庫,大小只有2KB。

Redux store提供了一些簡單的api來管理state,分別為:

  • getState: 取得目前application的state
  • dispatch(action): 發送action
  • subscribe(listener): 監聽state的變化
  • replaceReducer(nextReducer): 替換store當時使用的reducer來計算state

為了在console使用上面這些method,我們將剛剛建立的store和action匯出成全域變數
首先,在src下新增index.js,然後把store和action匯入

import store from "../store";
import { addArticle } from "../actions";

window.store = store;
window.addArticle = addArticle;

接著打開專案目錄下的index.js匯入src/index.js

import index from "./src";

準備工作都就緒囉,接著在terminal輸入yarn start打開localhost:8080
然後看到一片白白的頁面,打開chrome dev tools的console,
測試是否抓得到我們丟在全域的store和addArticle,執行結果如下:
https://ithelp.ithome.com.tw/upload/images/20181020/20111595ex9NVqcLrK.png

接著在console輸入store.getState()取得目前的state
得到{articles: Array(0)}

我們透過subscibe來監聽state,
subscribe會在action被觸發後執行callback。
註冊callback透過在console執行:

store.subscribe(() => console.log('Look ma, Redux!!'))

為了改變Redux的state,我們需要執行action
調用dispatch method執行action,
在console輸入:

store.dispatch( addArticle({ name: 'React Redux Tutorial for Beginners', id: 1 }) )

執行完後我們會看到

Look ma, Redux!!

接著透過store.state()再取得一次state,得到:

{articles: Array(1)}

console顯示畫面如下:
https://ithelp.ithome.com.tw/upload/images/20181020/20111595viVzZS4qfK.png


今日總結:
今天銜接了action和reducer,並實際操作了store的三個method:

  • getState: 取得目前application的state
  • dispatch(action): 發送action
  • subscribe(listener): 監聽state的變化

了解redux了stae、store、reducer和action後。
明天再來把redux和react整併使用!

本日完結。


上一篇
Day 12-初探Redux(store, reducer, action)
下一篇
Day 14-和Redux合作重寫todos吧!
系列文
React 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言