React Redux 源码简单分析

简单的使用示例:

import { Provider, connect } from './react-redux/src'
import { createStore } from './redux/src'
import rootReducer from './reducers'

const store = createStore(rootReducer)

function Child(props) {
  return <div>
    <div>name: {props.name}</div>
    <div>age: {props.age}</div>
    <button onClick={() => props.dispatch({
        type: 'CHANGE_NAME',
        data: Math.random()
      })}
    >
      change name
    </button>
    <button onClick={() => props.dispatch({
        type: 'CHANGE_AGE',
        data: Math.random()
      })}
    >
      change age
    </button>
  </div>
}

const mapStateToProps = state => {
  return {
    name: state.name,
    age: state.age
  }
}

const mapDispatchToProps = dispatch => ({
  onClick: () => dispatch()
})

const ConnectChild = connect(
  mapStateToProps,
  // mapDispatchToProps
)(Child)

function Demo() {
  return <Provider store={store}>
    <ConnectChild />
  </Provider>
}
export default Demo;

1. Redux 源码

源码:https://github.com/reduxjs/redux/tree/v4.1.0

index.js 导出了以下内容:

1.1 createStore

源码简化版:

  1. createStore 创建了一个 store 对象,含有 dispatch, subscribe, getState 等方法

  2. 大致原理是,内部通过闭包维护一个 currentState 属性,nextListeners 属性。nextListeners 对应 观察者模式 中的观察者列表。

  3. subscribe 方法可以往 nextListeners 中添加观察者

  4. 当调用 dispatch 方法是,会执行 currentState = currentReducer(currentState, action) 改变当前的 currentState 属性。之后会通知到所有的观察者去执行。

  5. getState 方法可以获取最新的 currentState 方法。

2. React-Redux 源码

源码地址: https://github.com/reduxjs/react-redux/tree/v6.0.0

在 React-Redux 7.1 版本之后,引入 hooks 写法,老实说,源码可阅读性有点下降(是的,我没看懂...),因此,我们还是看旧版本的代码吧,大致思想应该是一致的

2.1 Provider 源码

源码简化版:

  1. Provider 内部有 storeStatestore 两个 state

  2. 在 componentDidMount 时调用 store.subscribe(), 内部会重新 setState({ storeState }). 即当我们在子组件调用 dispatch 方法时, 会更新 Provider 组件的 storeState 状态。

  3. Provider 再通过 Context 将自己的 state 传递到子组件中

2.2 connectAdvanced.js 源码

  • connect()(Component) 包裹的组件, 会通过 selectDerivedProps(storeState, store) 从 storeState 中得到你需要的属性 derivedProps (通过计算你的 mapStateTopPropsmapDispatchToState 得出)

3. 原理总结

  1. 在 Redux 库中,createStore() 返回 store 对象,对象上有 { getState, dispatch, getState } 等属性 ,该对象传给 React-Redux 的 Provider 组件

  2. React-Redux 中的 Provider 组件中通过 store.subscribe 监听 store 的状态数据变化。每次数据变化后都会把状态数据用 Context API 传递到子组件

  3. 当调用 dispatch 方法时,在 Redux 中会通过 currentState = currentReducer(currentState, action) 也就是"过一遍" reducer 方法,得到最新的状态数据

  4. 此时子组件会得到最新的 state 信息,通过 selectDerivedProps(storeState, store) 来得到最终的 props,进行渲染。另外,如果发现从 store 中接受到的 props 没有发生变化,则不会重新渲染。

3.1 流程

Redux 中的三个概念:

  1. dispatch

  2. reducer

  3. state

至于 Action Creator, 实际上就是为了便捷的创建 action,有更好,没有也行

4. TODO

整理 compose,applyMiddleware,combineReducers,以及中间件的一个原理

Last updated

Was this helpful?