iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
1
Modern Web

React 30天系列 第 12

Day 12-初探Redux(store, reducer, action)

  • 分享至 

  • xImage
  •  

前情提要:
昨天我們先帶入了什麼是state,redux的任務其實也就是好好管理state,今天我們就來認識store、reducer和action吧!

Redux store

store在redux中負責協調所有的moving parts。
簡而言之,它就是大腦的角色!整個應用程序(application)的state都在store裡,所以要使用redux前我們應該要先建立一個可以容納所有資料的大腦store!
※特別注意:一個redux應用程序內只會有一個store。

回到我們建立的parcel開發環境先安裝redux。

yarn add redux

接著在src下建立store目錄,並在store目錄下新建一個檔案index.js,內容為:

import { createStore } from "redux";     // 1. 
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);  // 2. 
export default store;
  1. createStore來自redux
  2. 使用createStore建立store,reducer則是裡面的第一個參數,我們的範例使用“rootReducer”,而state就是由reducer產生。

Redux reducer

在Redux,state一定是透過reducer return。
Reducer其實只是javascript的function,而這個function內含兩個參數,第一個為current state,也就是目前state的資料,另一個則是action,如果我們想要更改store內的state資料,則要透過action的幫忙。

另外,還有一點要特別注意:state是不可變的。
等等,剛剛不是說改變state的資料可以透過action嗎?怎麼現在又說不能變?
這邊講的不可變是指immutable,我們希望state所有的更動都是透過action變換,而不是Object的mutable。

番外:immutable
一般在javascript裡Object是可變的(mutable)
比如說:

const foo = { age: 20 };
const bar = foo;
bar.age = 30;

console.log(foo.age);  // 30

可以看出mutable的影響造成非預期的資料異變,改變bar的age時,同時更改了foo的age,當我們的應用程序(application)變複雜時,就有可能因為mutable造成我們開發上的困擾。
所以像是Immutable.js, seamless-immutableimmutability-helper都是mutable的解套方案。

了解以上這些概念後,我們就來開始寫reducer囉!
首先,在src下建立reducers目錄
接著在reducers目錄下新建一個index.js檔案

  1. 初始化state,避免最開始取得的state是undefined
  2. 設定reducer function,第一個參數為state,第二個參數為action,目前action尚未被指派任務,而這個function目前只會回傳state。
const initialState = {  // 1. 初始化state
  articles: []
};
// 2.
const rootReducer = (state = initialState, action) => {
  return state;
};

export default rootReducer;

Redux action

在redux,reducer是最重要的概念。
redux產生整個應用程序(application)的state,那我們要怎麼知道下個state是什麼?怎麼產生新的state呢?
改變state的唯一方法,就是透過action,而“Dispatching an action”就是發送action的過程。
而action呢,其實不過就是javascript的object,action範例如下:

  1. type: 每個action都會有type屬性來描述state該怎麼改變。
  2. payload: 在下方的範例裡,payload是一篇新文章,reducer將在之後把這篇文章加到state。
{
  type: 'ADD_ARTICLE',
  payload: { name: 'React Redux Tutorial', id: 1 }
}

處理action最好的方法就是將每個action都包在function內,像這樣的function就是action creator
讓我們建立一個簡單的Redux action將所有內容放在一起吧!

先在src目錄下新增actions資料夾並新增檔案index.js

export const addArticle = article => {
  return { 
    type: "ADD_ARTICLE", 
    payload: article 
  };
}

建立常數
type屬性就是字串(string)。
reducer用type來決定怎麼計算下一個state,所以在reducer內也需要使用type。
由於string容易因為手殘眼花而打錯,所以最好把他先宣告成常數(constant),
這方法有助於避免麻煩的debug。

接下來我們來建立放常數的目錄。
在src目錄下新增constants資料夾並新增檔案action-types.js

export const ADD_ARTICLE = "ADD_ARTICLE";

接著再次打開src/actions/index.js調整我們的程式碼

import { ADD_ARTICLE } from "../constants/action-types";

export const addArticle = article => {
  return { 
    type: ADD_ARTICLE,   // 原本是字串,改匯入常數 
    payload: article 
  };
}

github傳送門

把action建好後,接下來就是把reducer和action整併囉!
這部分就留到明天吧!


今日總結:

  • Redux store就像大腦,他負責協調Redux的所有moving parts
  • 應用程式的state單獨存在,在store內是個不可變的物件(object)
  • 當store接收到action時就會觸發reducer
  • 由reducer來返回(return)下個新state
  • reducer是一個javascript function,內含兩個參數 (state和action)
  • reducer依據action type來計算下個state。此外,當沒有取到對應的action type時,至少應該要回傳initial state

參考資料:React Redux Tutorial for Beginners: The Definitive Guide (2018)


上一篇
Day 11-初探Redux(State)
下一篇
Day 13-Redux-Store的三個方法
系列文
React 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言