react-redux 懶人教程

書接上回 《redux懶人教程》,咱們已經學會了使用redux管理混亂的全局狀態,下面咱們一塊兒看看redux是怎麼幫助咱們管理react應用的狀態的。前端

react面臨什麼問題

咱們先捋一捋react的一些基礎概念,看看在什麼狀況下咱們才須要引入redux。react

react這樣的前端框架的功能一言歸納就是實現了數據和UI的實時映射。開發者只須要經過react組件管理數據,當數據變化時,react會讓其映射的UI實時更新。而組件的數據主要是兩個:state和props。props是父組件傳遞過來的數據,state是組件自身管理的數據,它又以props的形式傳遞給子組件。一個組件的props和state的變化都會引起該組件及其子組件對應UI的變化,也就是重渲染。 redux

例如上圖中,組件2傳遞給組件4的props變化會引起組件4的重渲染;組件1的state變化則會引起整個組件樹的重渲染。

props更像數據管道,state則比較像數據引擎。api

如今問題來了,組件4和組件7之間要怎麼通訊呢。全體起立,讓咱們再次大聲喊出這一句:數組

在計算機領域,若是有什麼事是加一層中間層解決不了的,那就加兩層bash

只須要把組件4和組件7須要通訊的數據提高到組件1上做爲組件1的state來管理,再經過props層層傳遞給組件4和組件7就好了。 OK,如今組件樹只有三層,經過這樣的方式或許還能夠接受,可是當組件樹有不少層的時候,你豈不是得寫不少次這樣的props傳遞的邏輯,這實在是太過辛苦而不優雅的一件事情了。所以,咱們也須要引入一個相似全局變量的東西,而react提供的context就是這個全局變量,它容許底層組件直接跨過中間組件,讀取頂層組件的數據,像這樣: 前端框架

而引入了全局狀態後,就像上一篇文章中講的那樣,因爲全局狀態比較重要,影響面甚廣,所以對它的修改須要比較謹慎,咱們就須要引入redux這樣的管理者來管理全局狀態。你看,整個過程是很是順其天然的,只有你的react應用足夠複雜的時候才須要使用redux,不然就不須要它。

react-redux是怎麼解決問題的

結合以前的內容,咱們明確:框架

  1. redux是用來管理全局狀態的
  2. react的全局狀態被放在頂層組件的context中

那麼如今你應該能解答這個這個靈魂之問了:要把redux裝進react,總共分幾步?ide

答:三步:函數

  • 第一步:制定數據管理規則並生成規則執行者,也就是設計reducer和action,生成store;
  • 第二步:將store放在react應用頂層組件的context中;
  • 第三步:react底層組件從context中取出store,對數據進行讀寫操做

咱們延續上一篇文章中管理一個數組的例子:

第一步,咱們已經完成了:

import { createStore } from 'redux';

const initState = [];
const reducer = (state = initState, action) => {
    switch(action.type) {
        case 'add':
            return [...state, action.addedItem];
        case 'delete':
            return [...state.slice(0, action.deletedIndex), ...state.slice(action.deletedIndex + 1)];
        case 'clear':
            return []
        default:
            return state;
    }
};

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

第二步,把store放進頂層組件的context中,這個頂層組件就是react-redux中的Provider組件:

import { createStore } from 'redux';
import { Provider } from 'react-redux';
import App from './App.js';

const initState = [];
const reducer = (state = initState, action) => {
    switch(action.type) {
        case 'add':
            return [...state, action.addedItem];
        case 'delete':
            return [...state.slice(0, action.deletedIndex), ...state.slice(action.deletedIndex + 1)];
        case 'clear':
            return []
        default:
            return state;
    }
};

const store = createStore(reducer);
ReactDOM.render(<Provider store={store}>
                    <App />
                </Provider>,
                document.getElementById('root');
複製代碼

第三步,底層組件從context中取出store對狀態進行讀寫。完成這一步時react-redux又把這個底層組件細分紅一父一子兩個組件,首先由一個父組件專門負責從context中取出store,把store管理的頂層狀態放在本身的數據引擎state中,用store.subcribe監聽頂層狀態的變化,頂層狀態一改變,這個父組件的數據引擎state就跟着改變,而後再把數據經過管道props傳遞給子組件。髒活累活都被父組件幹了,咱們開發子組件的時候只須要享用父組件傳遞過來的props就行了,真是父愛如山啊。另外,對頂層狀態進行操做的函數dispatch也須要經過props傳遞給子組件,這樣子組件才能夠修改頂層狀態嘛。思路已經理通了,react-redux還要作最後一點優化——由於父組件徹底不必直接把store管理的狀態整個傳給子組件,也不必把dispatch函數自己傳遞給子組件。假設頂層組件管理了100多個狀態,而實際上你在開發的底層組件可能只想讀寫其中的一個狀態而已——好比這個狀態叫theme,那麼我但願我寫底層組件時,徹底不用管其餘狀態是什麼,也不用管要修改其餘狀態須要dispatch什麼action,我只想經過props.theme讀狀態,經過props.setTheme()寫狀態。嗨呀其實這不就是加一箇中間層就能搞定的事嗎,而react-redux須要你寫的mapStateToProps函數和mapDispatchToProps函數就是專門用來幹這個的。

好了囉裏囉嗦一大堆,上面的這一段是告訴你要完成第三步都須要作什麼,這其中像從context中取出store這種又髒又累的重複性工做,已經被react-redux在connect這個高階組件中作完了。所謂高階組件,其實就是一個函數,傳給它一個組件,它返回一個新的組件。在connect這個高階組件中,你須要傳給他mapStateToProps,mapDispatchToProps以及你的業務子組件,它返回給你一個能讀寫store管理的狀態的組件。

talk is cheap, show you the code好伐:

import React from 'react';
import {connect} from 'react-redux';

const mapStateToProps = (state) => {
    return {
        array: state
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        addItem: (item) => {
            dispatch({
               action: 'add',
               addedItem: item
            });
        }
    }
};

const App = (props) => {
    return (
        <div>
            <div>{props.array}</div>
            <div>
                <button onClick = {props.addItem(1)}>在數組中添加一個1</button>
            <div>
        <div>
        
    )
};

export default connect(mapStateToProps, mapDispatchToProps)(App);
複製代碼

總結

最後,把react-redux的使用方法用下面這個圖歸納一下:

好了,到如今爲止redux的懶人教程系列就算完結了,筆者在寫的過程當中一直極力避免去詳細解析API的具體用法,或者太過深刻地解釋原理,主要是但願能幫助讀者花比較小的代價就能大體理解爲何要用redux/react-redux, 怎麼用redux/react-redux。 redux的主要生態是其豐富的中間件,也有實現類似功能的狀態管理工具mobx能夠學習,在react-hook風頭正盛之際,react-redux也提供了對應的hook api,在此就再也不一一介紹了,搞懂redux核心用法以後上手這些都會很快的。

水平有限,有哪些寫的不清不楚或者表述不正確的地方歡迎多交流指正,以爲有幫助的話求一個贊哦 :)

相關文章
相關標籤/搜索