React從入門到放棄之前奏(3):Redux簡介

来源:https://www.cnblogs.com/neverc/archive/2018/05/22/9071065.html
-Advertisement-
Play Games

安裝 概念 在redux中分為3個對象:Action、Reducer、Store Action 1. 對行為(如用戶行為)的抽象 1. Action 就是一個普通 JavaScript 對象。如: (其中type欄位是約定也是必須的) 1. 作為Reducer的參數 Reducer 1. 一個普通的 ...


安裝

npm i -S redux react-redux redux-devtools

概念

在redux中分為3個對象:Action、Reducer、Store

Action

  1. 對行為(如用戶行為)的抽象
  2. Action 就是一個普通 JavaScript 對象。如:{ type: 'ADD_TODO', text: 'Go to swimming pool' }(其中type欄位是約定也是必須的)
  3. 作為Reducer的參數

Reducer

  1. 一個普通的函數,用來修改store的狀態。
  2. 函數簽名:(currentState,action)=>newState
    1. 在 default 情況下返回currentState
    2. Object.assign({},state, { visibilityFilter: action.filter })(第一個參數不能為state) 等價於ES7的 { ...state, ...newState }
  3. redux 的 combineReducers 方法可合併reducer

Store

  1. 代表數據模型,內部維護了一個state變數
  2. 兩個核心方法,分別是getState、dispatch。前者用來獲取store的狀態(state),後者用來修改store的狀態
  3. createStore(reducer) 可創建Store

redux示例:

import { createStore } from 'redux'

// reducer
function counter(state = 0, action) {
    switch (action.type) {
        case 'INCREMENT':
            return state + 1
        default:
            return state
    }
}

// state
let store = createStore(counter); // 會調用

// 監聽
store.subscribe(() =>
    console.log(store.getState())
);

// 調用reducer
store.dispatch({ type: 'INCREMENT' });

react-redux

react的需求:

  1. 數據總是單向從頂層向下分發的
  2. 組件之間的溝通通過提升state:子組件改變父組件state的辦法只能是通過onClick觸發父組件聲明好的回調
  3. state越來越複雜:單頁應用的發展導致。包括伺服器響應、緩存數據、本地生成尚未持久化到伺服器的數據,也包括 UI 狀態,如激活的路由,被選中的標簽,是否顯示載入動效或者分頁器等等。

react-redux 將react組件分為2種:展示組件 和 容器組件

展示組件

描述如何展示:負責UI樣式的展示

  1. 數據來源:props
  2. 數據修改:通過props的回調函數
  3. 不直接使用redux

容器組件

描述如何運行:負責數據獲取 和 狀態更新

  1. 數據來源:redux state
  2. 數據修改:redux 派發action
  3. 直接使用redux

react-redux 只有2個API:Provider 和 connect

Provider

<Provider store>

  1. 在原應用組件上包裹一層,使原來整個應用成為Provider的子組件
  2. 接收Redux的store作為props,內部通過context對象傳遞給子孫組件上的connect

connect

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(Component)

作用:連接React組件與 Redux store

mapStateToProps(state, ownProps) : stateProps

  1. 將 store 中的數據作為 props 綁定到組件上。
  2. 當 state 變化,或者 ownProps 變化的時候,mapStateToProps 都會被調用,計算出一個新的 stateProps

mapDispatchToProps(dispatch, ownProps): dispatchProps:將 dispatch(action) 作為 props 綁定到組件上

mergeProps:指定 stateProps 以及 dispatchProps 合併到 ownProps 的方式。(預設使用Object.assign)

connect是個高階組件(HOC)大致源碼:

export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
  return function wrapWithConnect(WrappedComponent) {
    class Connect extends Component {
        constructor(props, context) {
            this.store = props.store || context.store
            this.stateProps = computeStateProps(this.store, props)
            this.dispatchProps = computeDispatchProps(this.store, props)
            this.state = { storeState: null }
            // 合併stateProps、dispatchProps、parentProps
            this.updateState()
        }
        shouldComponentUpdate(nextProps, nextState) {
            // 進行判斷,當數據發生改變時,Component重新渲染
            if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
                this.updateState(nextProps)
                return true
            }
        }
        componentDidMount() {
            this.store.subscribe( () => this.setState({ storeState: this.store.getState() }) )
        }
        render() {
            return (
                <WrappedComponent {...this.nextState} />
            )
        }
      }
      return Connect;
    }
}

react-redux示例:

Counter.js

import React, { Component } from 'react';
import { createStore, bindActionCreators } from 'redux';
import { Provider, connect } from 'react-redux';

function clickReduce(state = { todo: 1 }, action) {
    switch (action.type) {
        case 'click':
            return Object.assign({}, state, { todo: state.todo + 1 });
        default:
            return state;
    }
}

let store = createStore(clickReduce);

class Counter extends Component {
    render() {
        return (
            <div>
                <div>{this.props.todo}</div>
                <button onClick={this.props.clickTodo}>Click</button>
            </div>
        )
    }
}

// 方式1:
export default connect(state => ({ todo: state.todo }),
    dispatch => ({ clickTodo: () => dispatch({ type: 'click' }) }))(Counter)

// 方式2:
export default connect(state => ({ todo: state.todo }),
    dispatch => bindActionCreators({ clickTodo: () => ({ type: 'click' }) }, dispatch))(Counter);

index.js

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
import Clock from './Clock'

render((
<Provider store={store}>
    <Counter />
</Provider>), root);

在redux中,我們只能dispatch簡單的action對象。
對應的在react-redux中,我們只能定義同步的reducer方法。
下節將介紹在react-redux如何定義非同步方法。讓其更加適用於生產環境。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 冒泡排序 冒泡排序(buble sort)是一個比較入門的排序演算法。顧名思義,它根據將最大(或最小)的數依次冒泡從而實現排序。 如下圖所示,白色部分為待排序數組,紅色部分為已找出的“較大的”數,每次迭代只需從白色部分找出其中最大的數字,直至找出n-1個“較大的”數後,數組已排序。 註:找出n-1個“ ...
  • 因為要統計數據進行圖表展示,所以就簡單學習了 ECharts JS 的應用。它是一個純Javascript圖庫,它依賴於一個輕量級的Canvas庫 ZRender,並提供直觀、生動、互動式和高度可定製的數據可視化圖表。 其官網地址為:http://echarts.baidu.com 教程文檔地址:h ...
  • 前言 從事前端到現在也有快兩年了,平時也會收集整理一些筆記放在印象筆記,不過收集過之後就在沒有看過,經大佬指點,真正掌握一個知識點,最好的方式就是用自己的話把內容講明白,就開始將以前零散的東西整合一下,和各位道友一起提高。 操作數組 印象中數組有很多方法,系統的整理一下,放在自己家裡方便回頭查~ A ...
  • 本篇博客的分頁插件是在2017-11-10 的一篇博客的基礎上改造的(原博客地址:原生js版分頁插件),主要是優化了分頁按鈕的排列和顯示樣式,取消首頁和末頁的箭頭按鈕,改為數字按鈕,並始終把它們分別固定放置在上一頁按鈕的後面和下一頁按鈕的前面。另外在DOM操作上,用的是jQuery,當然如果不想使用... ...
  • 什麼?這是要做前端的節奏嗎?只要公司有需要,我分分鐘變身、前端、美工、UI、交互、後端、資料庫管理員......快速學習、快速響應,快速適應。公司需要我幹啥,我就幹啥,而我存在於公司的意義就是利用所學的東西幫公司解決問題......事實上,如果讓一個人來搞定整個項目包括移動端、PC端等等,那你還不是 ...
  • 2018年5月4日,Angular6.0.0版正式發佈,新版本主要關註底層框架和工具鏈,目的在於使其變得更小更快。下麵就介紹下新版本的一些主要新特性,供大家參考。 ng update ng update 是新增的一個cli命令。通過ng update不僅可以保持正確的版本依賴,而且能保持依賴關係的同 ...
  • javascript和css文件中採用相對路徑,其基準路徑是完全不同的。 1.javascript引用資源(比如圖片)相對路徑是以宿主路徑(被引用的網頁比如你在首頁index.php引用了某js文件,則index.php即為宿主)所處位置為基準。 2.css引用資源(比如圖片)相對路徑是以.css文 ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...