iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 18
1
Modern Web

寫React的那些事系列 第 18

React Day18 - Redux 三大原則

  • 分享至 

  • xImage
  •  

做完React todos會發現,在React中畫面的呈現與資料內容都會是由state來管理,當要存的狀態越來越多的時候,state就會顯得有點難管理。React是單向資料流(Unidirectional Data Flow),最上層會有一個root component,它會keep住所有state和所有控制state的 function,再把這些state和function往下傳遞,所以很容易顯得有點繁瑣複雜。

Redux的出現可以幫忙管理這些繁瑣的事情,把state tree放在store,用actions發送事件給reducer來改變state,而在action和reducer中間還可以使用middleware做一些事情,middleware的部分後面會再特別介紹。今天會先簡單說明,Redux的三大原則,這樣我們之後實作,會更清楚這些觀念!

(1)Single source of truth


The state of your whole application is stored in an object tree within a single store.

前面有提到React管理畫面呈現或是資料內容的都是state,在Redux把它們統一存在一個叫做 store 的object tree中(也可以稱為state tree),所以說它是single source of truth,資料的唯一來源。

這邊以todos的state為例,再加上一個state記錄task完成狀態的fliter,以下就會是我們的store:

{
  filter: 'SHOW_ALL',
  todos: [
    {
      task: 'Install packages',
      isCompleted: false
    },
    {
      task: 'Add webpack.config.js',
      isCompleted: false
    },
    {
      task: 'Break UI into components',
      isCompleted: false
    }
  ]
}

(2)State is read-only


The only way to change the state is to emit an action, an object describing what happened.

這邊的read only是指說state只能透過action去改變它,而不能任意的改變。Action是由一個plain object組成,透過這樣的指令,讓我們很容易做action的管理,紀錄發生action的順序,甚至也可以做undo的功能,這是透過用action來改變state的好處。

以下是action的寫法:

{
  type: 'FINISH_TASK',
  isCompleted: true
}

透過store發送action:

store.dispatch({
  type: 'FINISH_TASK',
  isCompleted: true
});

(3)Changes are made with pure functions


To specify how the state tree is transformed by actions, you write pure reducers.

Reducer就是pure function,action發送要改變的指令給reducer,reducer會收到action和前一個state當參數,並回傳新的state改變state,reducer不可以直接改變前一個state。而所謂的pure function,表示reducer return的值是要可以被預測的,不可以在function中做Math.random()或是fetch api,這些動作應該在action被dispatch時就先處理完成,必須保持 reducer is pure

以下是reducer和設定reducer的方式:

// 處理filter的reducer
function filter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_FILTER':
      return action.filter;
    default:
      return state;
  }
}

// 處理todos的reducer
function todos(state = [], action) {
  ... // 先略過內容
}


// 使用reducer來建立store,因為每個reducer都處理對應的state
import { combineReducers, createStore } from 'redux';

let reducer = combineReducers({ filter, todos });
let store = createStore(reducer);

Redux Flow


http://ithelp.ithome.com.tw/upload/images/20161217/20078318mmLJLxvLSZ.png

上面這張圖說明Redux的整個流程,view就是我們的components,當user有一些操作或是某個特定情況,觸發action,store.dispatch要改變的事件內容,透過store傳給reducer,傳入prev state和action,reducer產生新的next state。當state tree被更新,就會引發view的re-render,這就是完整Redux的流程!

Redux最主要就是store、action、reducer這三個項目組成,先稍微理解這三個大原則,還有一些小細節可以說的,會再後面仔細介紹它們!

參考


Redux - Three Principles


上一篇
React Day17 - 在React中使用class
下一篇
React Day19 - Redux Action
系列文
寫React的那些事31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言