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核心用法以后上手这些都会很快的。

水平有限,有哪些写的不清不楚或者表述不正确的地方欢迎多交流指正,以为有帮助的话求一个赞哦 :)

相关文章
相关标签/搜索