Redux 知識點梳理和實踐

以前在有道雲筆記上寫過一篇 Redux 學習實踐的文章,附帶了一個小 Demo。因爲一段時間沒看 Redux,加上以前缺少足夠的練習,如今想重構我的博客,使用 Redux 進行狀態。如今不得不回頭再看看 Redux 相關東西。這裏順便記錄下學習筆記,一來便於回顧,二來但願對他人有所幫助。筆記同步寫在我的博客網站java

這篇文章是知識點的梳理,若是你對 Redux 的基礎有必定了解,閱讀起來可能比較合適。react

什麼是 Redux?

Redux 能夠說是 Flux 架構思想的最佳實踐方案,用於對大型、複雜、多數據來源的 React 進行數據管理。遵循 Redux 的設計原則,再配合 React 容器組件、展現組件分離的代碼組織原則,可讓咱們的項目結構清晰,數據流清晰,十分利於項目的維護開發。git

Redux 設計的三大原則

  1. 單一的數據來源,全部的數據保存在一個對象中。
  2. 狀態只讀,Reducer 根據 store dispatch 的 action 類型返回一個新的狀態,不修改原來的狀態。
  3. 狀態修改均由純函數完成。

關於這三大原則的深刻理解建議參考 《深刻React技術棧》、《深刻淺出React和Redux》github

淺談 Redux 的工做過程(和 MVC 的主要區別)

有 MVC 框架使用經驗的同窗應該清楚,MVC 的工做過程是這樣:view 層將用戶行爲傳遞到 controller 中的action, controller 中的 action 和 Model 層交互操做數據,返回到 view。一般 MVC 框架的實現 M 和 V 層是能夠交互的,這樣數據就不是單向流動,這種設計不少場景下很靈活,寫起來很爽快,可是要項目過大,項目數據流複雜,項目維護就不爽了。redux

Redux 則嚴格遵循上面提到的設計三大原則,工做過程是這樣的:view 層觸發一個 action,這個 action 由 store.dispatch(action) 傳遞給 reducer,reducer 根據 previousState 和 action type 返回一個新的 state(不修改數據), 如此實現了數據的變動。數組

Redux 核心 API

上面 Redux 的工做過程提到了 Redux 有 store、action、reducer 這些概念,這些都是 Redux 對外提供的核心 API,咱們來看看他們分別是幹嗎的。bash

  1. store架構

    store 做爲整個應用數據的惟一來源,用於保存數據和 dispatch action。store 使用 Redux 提供的 createStore 方法來生成。框架

    import { createStore } from 'redux';
    let store = createStore(reducer)
    複製代碼

    createStore 接受一個 reducer 做爲參數,返回一個 store 對象。store 對象包含 4 中方法:dom

    getState():// 用於獲取 store 中當前的狀態
    dispatch():// 用於分發 action,這個是改變 store 中數據的惟一方式
    subscribe(listener):// 註冊一個監聽者,在 store 發生變化時被調用
    replaceReducer(nextReducer):///更新當前 store 中的 reducer
    複製代碼
  2. reducer

    reducer 本質上是一個函數,這個函數能接受一個 action 和一箇舊的狀態(previousState),根據 previousState 和 action 返回新的狀態

    reducer(previousState, action) => newState
    複製代碼

reducer 必須是一個純函數,不能修改原來狀態,關於純函數的概念請閱讀其餘資料學習。

  1. action

    reducer 的 action 本質上是一個 javaScript 對象,這個對象必須有一個 type 屬性,用來代表 action 的類型,還能夠有 payload, error, meta 屬性。關於 action 對象的屬性,社區有個規範,能夠參考github.com/redux-utili…

    const action = {
        type: 'ADD_TODO',
        payload: 'todo'
    }
    複製代碼

    reducer 就是根據 action type 屬性來決定返回新的 state。

先睹爲快

我在學習 Redux 的時候,看了不少文檔,認爲對 Redux 的概念瞭然於胸,可是動手寫第一個小 Demo 的時候仍然以爲很難下手,多是 Redux 這些概念對我而言太新。這裏給出我寫的第一個小 Demo。

這個 Demo 實現了點擊按鈕讓數字加一減一的功能,沒有任何複雜度,單純的是爲了瞭解 actionstorereducer 的具體做用和協做關係。

Demo 地址: github.com/wewin11235/…

爲了便於觀察,Demo 的代碼都丟在了一個文件裏,在實際開發中,必定要遵循好的代碼組織原則。

import React from 'react';
import ReactDOM from 'react-dom';

// 建立 action
// action 是 javaScript 對象,是用戶行爲的抽象,必須包含一個 stype 字段
// 根據 Demo 須要實現記數功能,抽象出兩種 action, 一種表示加,一種表示減
const incream_action = { type: 'INCREAM' };
const decream_action = { type: 'DECREME' };

// 建立 reducer
// reducer 接受一個 previousState 和 action 返回一個新的 state
const reducer = (state=0, action) => {
  switch (action.type) {
    case incream_action.type:
      return state + 1;
    case decream_action.type:
      return state - 1;
    default:
      console.log('default');
      return state;
  }
}

// 建立 store
// store 建立使用 createStore(reducers)
// createStore 由 redux 提供
import { createStore } from 'redux';
let store = createStore(reducer);

// 建立計數組件
class Counter extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const { count, doIncrement, doDecrement } = this.props
    return(
      <div>
        <span>{count}</span>
        <button onClick={doIncrement}>+</button>
        <button onClick={doDecrement}>-</button>
      </div>
    )
  }
}

const render = () => ReactDOM.render(
  <Counter
    count={store.getState()}
    doIncrement={() => store.dispatch(incream_action)}
    doDecrement={() => store.dispatch(decream_action)}
  />,
  document.getElementById('root')
);

render();

// 爲了能在 store 發生變化後能刷新頁面,須要給 store 註冊一個監聽事件
// store 變化後,刷新頁面
store.subscribe(render);
複製代碼

最小 Redux 應用誕生。

歡迎指正,補充!

相關文章
相關標籤/搜索