十分鐘理解Redux核心思想,過目不忘。

白話Redux工做原理。淺顯易懂。
若有紕漏或疑問,歡迎交流。

Redux 約法三章

惟一數據源(state)

雖然redux中的statereact沒有聯繫,但能夠簡單理解爲react組件中的this.state
html文檔只是state的一種表現形式。全部html的數據應該都是直接間接來自於state,不然UI視圖是沒法因state改變而更新的。html

數據源(state)只讀

不該該直接修改state數據。
對於數組使用:react

Array.prototype.slice()//對數組進行拷貝
//使用ES6: 
[...state, ...newState]

對於對象使用:編程

Object.assign({}, state, change1, change2...)//對對象進行拷貝
//使用ES6:
{...state, ...newState}

經過純函數(pure function)改變數據源(state)

pure function: 無其餘API(包括Math, Date等)調用,無異步操做,preState => newState。redux

Redux數據流

簡單介紹store/reducer/action, 比較簡潔,請牢記於心。數組

store
UI惟一數據來源,能夠理解爲react中的state,store信息的變化會觸發視圖更新.異步

action
對象。必須擁有type屬性,用來描述發生什麼。可選擇攜帶發生時的數據,如用戶輸入的input value。切記:僅僅用來表述發生了什麼。函數

reducer
pure function(上面有解釋)。根據action.type來作出反應,(preState, action) => newState,生成的state是用來改變store的。學習

因此,data flow(數據流):this

  1. UI發出動做,如click, submit;
  2. action, 描述發生了什麼;
  3. reducer處理髮生的事情,生成新state;
  4. store被更新;
  5. UI響應store更新
  6. ...

Redux action

舉幾個例子,可能會比較直觀:spa

{
  type: 「TOGGLE_TODO」, //這個type屬性必需要,必須是字符串
  index: 5 //附加信息,本身根據須要選擇是否加入
};
{
  type: 「ADD_TODO」,
  text:「學習Redux」 //附加信息,這裏是input value
}

沒別的,就是這麼簡單。
有時候可使用action生成器(action creators)來批量生產類似action對象,如:

//我須要根據不一樣的input value來生成高度類似的action:
function (text) {
  return {
    type: "ADD_TODO",
    text: text //附加的信息
  }
}

說明
雖然上面數據流提到,action經過reducer處理生成newState後纔可以更改store信息。可是爲了更好的語義編程,Redux經過語句store.dispatch(action)來更新store,reducer對action的處理在內部處理。

Redux reducer

很簡單

(theState, action) => (newState);
//僅僅只是根據action.type處理一下須要更新的state

來看一個相對完整的reducer:

function todoApp(state = initialState, action) { //注意須要處理undefined狀況下的state默認值
  switch (action.type) {  //根據action.type來判斷
    case "SET_VISIBILITY_FILTER":
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    case 「ADD_TODO」:  //處理「ADD_TODO」的action type
      //返回新state(newState),注意不要直接改變state,對象使用了
      //Object.assign()。也可使用ES的...操做符
      return Object.assign({}, state, {
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      })
    case 「TOGGLE_TODO」:  //處理「TOGGLE_TODO」的action type
      return Object.assign({}, state, {
        todos: state.todos.map((todo, index) => {
          if (index === action.index) {
            return Object.assign({}, todo, {
              completed: !todo.completed
            })
          }
          return todo
        })
      })
    default:
      return state
  }
}

Redux store

store
UI視圖惟一數據來源(直接或間接),能夠獲取state,更新state,監聽state變化,取消監聽。因此store提供了一下方法:

  1. store.getState() 獲取當前state
  2. store.dispatch(action) 更新state
  3. store.subscribe(listener) store更新後回調listener,回調函數裏面能夠調用store.getStore()來獲取更新後得state喲~
  4. 取消listener的方式比較特別:調用一次store.subscribe(sameListner)

ps: 若有紕漏或疑問,歡迎交流。先寫這麼多,有時間繼續更新。

相關文章
相關標籤/搜索