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 (
); } } const store = createStore(rootReducer, { activeTab: 0, }); ReactDOM.render( , 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 (

{activeTab}

); } } 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 (
      
        {this.props.children}
      
    )
  }

构造函数和生命周期一看,基本上知道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相关的代码里,自己看?)

你可能感兴趣的:(源码解读)