redux、react-redux执行流程简单解析

其实不想看react-redux、redux的源码,平时不太喜欢用,尤其是简单的页面,然而总是会遇到复杂点的页面的,所以还是要了解下,搜索了下,讲react-redux、redux的文章很多,但是,好像都不太能理解,可能是风格不太一样,没办法还是只能自己看,看了就记录下吧。

只讲最简单的使用涉及的东西,目前没怎么用中间件什么的。react-redux版本6.0.1,redux版本4.0.1

使用的例子如下:

main.jsx文件

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

import Comp1 from "./comp1";
import {createStore} from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers';

class App extends React.Component {
  render() {
    return (<div>
      <Comp1 />
    </div>);
  }
}

const store = createStore(rootReducer, {
  activeTab: 0,
});

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>, document.getElementById("app"));


=====
comp1.jsx文件

import React, { Component } from "react";
import { connect } from 'react-redux';
import { changeTab } from './actions';

class Comp1 extends Component {
  render() {
    const {activeTab, changeTab} = this.props;
    return (
      <div>
        <p>{activeTab}</p>
        <button onClick={()=>changeTab(33)}>click</button>
      </div>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
  activeTab: state.activeTab,
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  changeTab: (val) => {
    dispatch(changeTab(val))
  }
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Comp1);

=====
actions.js文件

export const changeTab = (val) => ({
  type: 'change_tab',
  activeTab: val
})

=====
reducers.js文件

export default (state = [], action) => {
  switch (action.type) {
    case 'change_tab':
      return {...state, activeTab: action.activeTab};

    default:
      return state;
  }
};

就是一个main里面渲染了一个子组件,子组件渲染了一个p标签和一个按钮,初始化activeTab等于0,按一下按钮变成了33。看一下整个过程涉及了哪些东西,首先是redux里的createStore,然后是react-redux的Provider和connect,没了,另外都是我们自己写的东西了。

createStore

先来看一眼createStore干了啥,打开redux/src/createStore.js看,createStore接收三个参数reducer, preloadedState, enhancer,最后一个不管它,第一个是我们自己写的reducer,第二个是初始化的时候的state。先翻到createStore函数的最后,看到

dispatch({ type: ActionTypes.INIT })

return {
  dispatch,
  subscribe,
  getState,
  replaceReducer,
  [$$observable]: observable
}

其中getState和replaceReducer比较简单,不说了,看subscribe这个名字应该能看出来这就是个发布订阅,subscribe是注册监听事件的函数,里面有这么一句nextListeners.push(listener),dispatch是调用reducer,并执行监听事件的地方,可以在里面看到

currentState = currentReducer(currentState, action)

...省略一些代码

const listeners = (currentListeners = nextListeners)
    for (let i = 0; i < listeners.length; i++) {
      const listener = listeners[i]
      listener()
    }

看到这里你会问,是谁调用了subscribe呢?dispatch又是谁调用的呢?不出意外就是react-redux了

Provider

我们打开react-redux/src/components/Provider.js来看,发现Provider是个react组件,看Provider做了什么

constructor(props) {
    super(props)

    const { store } = props // 这个store就是我们用redux的createStore生成的那个store

    this.state = {
      storeState: store.getState(), // 看一眼
      store
    }
  }

componentDidMount() {
    this._isMounted = true
    this.subscribe() // 看一眼
  }

componentWillUnmount() {
    if (this.unsubscribe) this.unsubscribe() // 看一眼
    this._isMounted = false
  }

componentDidUpdate(prevProps) {
    if (this.props.store !== prevProps.store) {
      if (this.unsubscribe) this.unsubscribe() // 看一眼

      this.subscribe() // 看一眼
    }
  }

...省略一些代码

render() {
    const Context = this.props.context || ReactReduxContext

    return (
      <Context.Provider value={this.state}>
        {this.props.children}
      </Context.Provider>
    )
  }

构造函数和生命周期一看,基本上知道Provider做了什么事情了吧,redux的createStore里的subscribe函数就是Provider调用的,那么再来看this.subscribe函数干了啥

subscribe() {
    const { store } = this.props

    this.unsubscribe = store.subscribe(() => { // 调用redux的createStore里的subscribe函数了
      const newStoreState = store.getState()

      if (!this._isMounted) {
        return
      }

      this.setState(providerState => {
        // If the value is the same, skip the unnecessary state update.
        if (providerState.storeState === newStoreState) {
          return null
        }

        return { storeState: newStoreState }
      })
    })

    // Actions might have been dispatched between render and mount - handle those 看一眼这个注释
    const postMountStoreState = store.getState()
    if (postMountStoreState !== this.state.storeState) {
      this.setState({ storeState: postMountStoreState })
    }
  }

connect

还剩最后一个connect函数,就是调用dispatch的地方,这个部分怎么说呢,我还没看懂哈哈哈,比较复杂,我们的例子里,mapDispatchToProps的参数dispatch其实就是redux的creatStore里的那个dispatch,感兴趣的同学可以深究,我这里就不继续了(逃走),实在不好意思,不过我们的流程已经通了,嗯,很好(?)。

总结

简单总结一下:redux就是个发布订阅,提供了subscribe和dispatch,react-redux在Provider里进行subscribe,connect的参数mapDispatchToProps里的dispatch就是redux的dispatch,用react的context API来实现更新机制(这部分上面没提到,也在connect相关的代码里,自己看?)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值