Redux 學習總結筆記

項目驅動是學習框架很是高效的一種方式。
學習 redux 全家桶推薦 react-douban:一個 React + Redux + React-Router 完整項目javascript

該筆記主要是下面三部分:前端

  • Redux 介紹、基本概念和API和工做流程
  • 中間件原理介紹及使用
  • redux-thunk 的用法

Redux 介紹

Redux是什麼?有什麼做用?

Redux是一個管理狀態容器,將整個前端應用的狀態都統一到一個地方管理。經過單一數據流操做,來實現單一狀態。使得前端應用更加方便的管理狀態。java

核心概念

整個state就是一個object,能夠將store理解爲前端的數據庫,沒有setter,不能直接更改。
若是要更改state,則須要dispatch an action。而 action 則是一個對象,用於描述提交了什麼操做,而不涉及對 state 具體的操做。
強制使用action來改變每一次的state,可讓咱們更加容易追蹤到每次state的變化。
而 Reducer 則是用來將 Action 和 State 串起來的一個函數。用於具體處理對 state 的改變。react

以上的過程差很少就是整個 Redux 的思想。git

Redux 三大原則

Single source of truth(單一數據源)

在你的應用中state存儲在一個 object tree,並且這個object tree 在該應用中是惟一一個的。
將全部state存在於應用中惟一一個object tree 帶來的好處是:能夠實現開發環境下的保存狀態的歷史狀態,實現Undo/Redo等功能。github

State is read-only(State 只讀性)

改變 state 的惟一方式就是觸發一個 action(action 是一個用於描述發生了什麼的對象)數據庫

Changes are made with pure functions(使用純函數進行更改)

爲了描述action 如何具體改變 state tree,你須要編寫reducers。Reducer 只是一些純函數。
Reducer 接收 state 和 action 做爲參數,並返回新的 state。json

基本概念和api

Store

Store就是保存數據的地方,能夠看出是一個容器,整個應用就只能有一個store。Redux提供createStore()函數來生成storeredux

import {createStore} from 'redux'

const store = createStore(app);複製代碼

State

store 某個節點對應的數據集合就是state。能夠經過store.getState()得到。
Redux 規定,一個state對應一個View。State相同,則View相同。api

Action

State 的變化會致使 View 的變化。可是用戶接觸不到State,只能接觸到View。因此State的變化必須是View致使的。Action就是View發出的通知,表示State要發生改變了。
Action是一個對象,其中type屬性是必須的,表示Action的名稱。其餘屬性隨意。

Action Creator

用於生成Action 的函數。

store.dispatch()

store.dispatch()是View發出Actiion 的惟一辦法。

import {createStore} from 'redux'
const store = createStore(fn);
store.dispatch(addTodo(text))複製代碼

Reducer

Store 收到Action以後,必須給出一個新的State,這樣才能使View發生變化。這種State的計算過程叫作Reducer。
Reducer 是一個函數,它接受Action和當前的state做爲參數,返回一個新的state。
整個應用的初始狀態,能夠做爲state的默認值。

Reducer還能夠進行拆分,而後經過combineReducers方法,結合成一個大的Reducer。

Redux工做流程

首先用戶發出Action。

store.dispatch(action)複製代碼

而後store自動調用Reducer,而且傳入兩個參數:當前的state收到的Action. Reducer 會返回新的state。

let nextState = reducer(previousState, action)複製代碼

State一旦變化,Store就會調用監聽函數。Listener能夠經過store.getState()獲得當前狀態。

第二部分:redux 中間件

中間件與異步操做

Redux解決了同步狀態更新的問題,可是異步操做卻沒有解決。
若是要 使Reducer在異步操做結束後自動執行,必須使用中間件。

applyMiddleware

createStore()方法包含了參數applyMiddleware(),
它是Redux的原生方法,做用是 將全部的中間件組成一個數組,依次執行

異步操做的基本思路

異步操做須要發出三種Action

  • 請求發起時的Action
  • 請求成功時的Action
  • 請求失敗時的Action

因此流程也很清楚:

  1. 操做開始時,dispatch action,觸發State更新爲正在操做狀態
  2. 操做結束後 再次 dispatch action,獲取結果

解決方案:
寫出一個返回函數的 Action Creator,而後使用redux-thunk中間件改造store.dispatch

import {createStore, applyMiddleware} from 'redux'
import thunk from 'react-thunk'

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
)

export function fetchPost() {

}
export function requestPost(){}

export function receivePost(){}

export function handleError(err) {

}

export function requstAync() {
  return function(dispatch){
    // 請求發起時 dispatch action
    dispatch(requestPost())
    // 這裏的fetchPost 是一個Promise
    return fetchPost()
    .then(response => response.json())
    .then(json =>
     // 請求成功時 dispatch action
      dispatch(receivePost())
    )
    .catch(err =>
     // 請求錯誤時 dispatch action
      dispatch(handleError(err))
    )
  }
}複製代碼

第三部分:redux-thunk用法

React-Redux將組件分爲兩種:

  • UI組件(純組件)
  • 容器組件

UI組件特色

  • 只負責UI顯示,不帶任何邏輯
  • 無狀態組件
  • 全部數據都是經過props提供
  • 不使用任何Redux的API

容器組件

  • 負責管理數據和業務邏輯,不負責UI顯示
  • 帶有內部狀態
  • 使用Redux API

若是遇到一個組件既有UI和業務邏輯時,須要拆分紅下面的結構:
外面是一個容器組件,裏面包含若干個UI組件。容器組件負責與外部的通訊、傳遞數據給UI組件。
UI組件則負責頁面顯示。

connect

用於從UI組件生成容器組件。能夠這麼來理解 connect 的做用。
connect 就是將 state 上的 props(屬性)和 方法(dispatch)添加到對應的 UI組件上。

import {connect} from 'react-redux'
import {TodoList} from './TodoList'
export default connect()(TodoList)複製代碼

上面的代碼就將UI組件 TodoList 轉換爲一個容器組件。
每一個容器組件須要定義兩方面的信息:

  • 輸入邏輯:外部的數據(即state對象)如何轉換爲 UI 組件的props
  • 輸出邏輯:用戶發出的動做如何變爲 Action 對象,從 UI 組件傳出去

完整的connect 方法的API以下:

import {connect} from 'react-redux'
import {TodoList} from './TodoList'

function mapStateToProps(state){
  return{
    // do something
  }
}

function mapDispatchToProps(dispatch){
  return{
    // do something
  }
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)複製代碼
相關文章
相關標籤/搜索