Redux 基礎教程以及結合 React 使用方式

本文教你實現一個最簡單的 Redux 應用,以及結合 React 如何使用。react

Redux簡介

概念

狀態管理工具,使用以後能夠清晰的知道應用裏發生了什麼。數據如何修改,如何更新的。git

出現的動機

之前我剛接觸 Redux 這類狀態管理工具的時候就在想:爲何須要這些東西呢,刷新數據就消失了,也不能持久化存儲數據,有啥用呢? 後來慢慢的應用越作越多,功能越作越複雜,就會發現,不少數據什麼緣由修改的,何時修改的,本身是一臉懵逼。啥也想不起來了,維護起來真的痛苦。到了這個時候才發現 Redux 這類工具的厲害之處。名字也很應景的,狀態管理工具。說的很清楚了,就是管理狀態的。讓數據變化過程儘量的清晰、可預測。github

在項目中添加 Redux 並非必須的。請根據項目需求選擇是否引入 Reduxnpm

三大原則

  • 單一數據源 整個應用的 state 被儲存在一棵 object tree 中,而且這個 object tree 只存在於惟一一個 store 中。redux

  • State 是隻讀的 惟一改變 state 的方法就是觸發 action,action 是一個用於描述已發生事件的普通對象。數組

  • 使用純函數來執行修改 爲了描述 action 如何改變 state tree ,你須要編寫 reducers。bash

Redux 三要素

  • Action(將要發生的操做)app

  • Reducer(根據 action 更新 state,是一個純函數)ide

    • 提供 combineReducers(reducers) 函數組合多個 reducer
  • 存放 state 數據的 Store(將 action 和 reducer 聯繫到一塊兒的對象)函數

    • 提供 getState() 方法獲取 state

    • 提供 dispatch(action) 方法更新 state

    • 經過 subsctibe(listener) 註冊監聽器

    • 經過 subscribr(listener) 返回的函數註銷監聽器

示例代碼

說了這邊文章是教你建立一個最簡單的 Redux 應用,那咱們下面就看看使用一個 Redux 到底能有多簡單,多快呢。

使用前先引入 Redux:npm install redux -S

  • 先來個 Action 三要素之一不就是有 Action 麼,有咱們就先寫一個 Action 建立函數唄

    Action 建立函數,是一個返回 action 的函數,非必須這樣寫,只是更方便移植和複用,建議使用 Action 建立函數來生成 action

    function increment() {
        return {
            type: "INCREMENT"
        }
    }
    複製代碼
  • 有了Action,還要有 Reducer 來執行更新啊 Reducer 既然必不可少,就在寫一個 Reducer。(這裏可能會有點迷糊,reducer 不是一個對象,而是一個返回更新後 state 的純函數)

    /** * counters 就是一個 reducer,根據傳入的 action 的 type 不一樣,返回一個新的 state 數據 */
    // 先初始化 state
    const initCounter = 0;
    function counters(state = initCounter, action) {
        switch(action.type) {
            case 'INCREMENT':
                return state ++;
            default:
                return state;
        }
    }
    複製代碼
  • 還得有一個存放 state 數據的 store 吧 如今要把咱們寫好的 Action 和 Reducer 鏈接起來

    • 先經過 reducer 建立 store
    const { createStore } = require('redux');
    
    const store = createStore(counters);
    複製代碼
    • 經過 store.dispatch(action) 將 action 發送給 reducer,更新 state
    store.dispatch(increment());
    複製代碼
  • 查看結果

    就這三步,操做完了吧,那咱們如今能夠看一下結果了

    // 經過 store.getState() 獲取 State 數據
    console.log('counters: ', store.getState());   // => counters: 1
    複製代碼

過程總結:

建立一個操做指令 action -> 建立一個 reducer -> 經過 createStore(reducer) 建立一個 store -> 經過 store。dispatch(action) 執行 reducer 中的更新操做,更新 store 中的數據。


這些就是 Redux 的核心用法,有沒有感受很簡單的,有興趣的話能夠跟我一塊兒繼續往下,看一看結合 React 該如何使用呢。


結合 React 使用

React-Redux

用來組合 React 和 Redux 配合使用的插件

以 create-react-app 腳手架爲例,請先使用 create-react-app 建立一個本地項目。本例中默認 create-react-app 已全局安裝過了

$ npm npm init react-app react-redux-todos
$ cd react-redux-todos
複製代碼

插件安裝

$ npm install redux react-redux -S
複製代碼

配合組件使用

  • 在組件根目錄使用 react-redux 提供的 Prodiver 標籤包裹

    import { Provider } from 'react-redux';
    
    <Provider store={ store }> ... </Provider>
    複製代碼
  • 在須要用到 state 或 action 的組件中使用 connect 高階組件進行包裝

    import { connect } from 'react-redux';
    import { createAction } from './actions'
    
    // mapStateToProps 編寫方式
    const mapStateToProps = (state) => {
        return {
            reducer: state.reducer
        }
    }
    
    // mapDispatchToProps 編寫方式
    const mapDispatchToProps = (dispatch) => {
        return {
            createAction: text => dispatch(createAction(field));
        }
    }
    
    // 使用 connect 將 state 和 dispatch 包裝到 Component 的屬性中
    export default connect(mapStateToProps, mapDispatchToProps)(Component);
    複製代碼
  • 在組件中就能夠經過 this.props.reducer 和 this.props.createAction 的方式獲取數據以及調用 action 了

TodoList 示例

示例代碼

預覽地址

擴展

Reducer 的 combineReducers 方法

當有多個 reducer 時,建立 store 以前須要將它們先進行合併

import { combineReducers } from 'redux';

// 合併成一個 reducers
const reducers = combineReducers({
    a: doSomethingWithA,
    b: processB,
    c: c
});
複製代碼

Store 的 subscribe 方法

  • 調用 store.subsctibe(listener) 註冊監聽事件 store 中的數據發生變化時,就會調用 listener 函數

    /** * 經過 store.subscribe(function) 註冊一個監聽器。每次 state 更新時,都會打印輸出日誌 */
    store.subscribe(() => console.log(store.getState()));
    複製代碼
  • store.subscribe(listener) 的返回值是一個 註銷監聽的函數

    /** * store.subscribe(func) 會返回一個函數,執行這個函數能夠註銷監聽器 */
    // 返回一個函數 unsubscribe
    const unsubscribe = store.subscribe(() => console.log(store.getState()));
    // 執行這個函數能夠註銷監聽器
    unsubscribe();
    複製代碼

若是還沒看夠

Redux 中文文檔

這裏有關於 Redux 最詳細的介紹和講解,我就很少此一舉了,有興趣的同窗能夠去看看哈。

相關文章
相關標籤/搜索