zoukankan      html  css  js  c++  java
  • react-redux源码解析

    一、 react-redux 和 redux是两个东西。在做react项目的时候,一般用react-redux和redux搭配起来开发。redux主要是做数据、状态的管理,而react-redux主要是方便数据redux在react使用。

    二、源码解析

    1)、 入口文件index.js

     1 import Provider, { createProvider } from './components/Provider'
     2 import connectAdvanced from './components/connectAdvanced'
     3 import connect from './connect/connect'
     4 
     5 /*
     6     对外暴露的API
     7     Provider,
     8     createProvider,
     9     connectAdvanced,
    10     connect,
    11     根据每个APi追溯其源头
    12  */
    13 export { Provider, createProvider, connectAdvanced, connect }

    2)、Provider.js 

     1 import { Component, Children } from 'react'
     2 import PropTypes from 'prop-types'
     3 import { storeShape, subscriptionShape } from '../utils/PropTypes'
     4 import warning from '../utils/warning'
     5 
     6 let didWarnAboutReceivingStore = false
     7 function warnAboutReceivingStore() {
     8   if (didWarnAboutReceivingStore) {
     9     return
    10   }
    11   didWarnAboutReceivingStore = true
    12 
    13   warning(
    14     '<Provider> does not support changing `store` on the fly. ' +
    15     'It is most likely that you see this error because you updated to ' +
    16     'Redux 2.x and React Redux 2.x which no longer hot reload reducers ' +
    17     'automatically. See https://github.com/reduxjs/react-redux/releases/' +
    18     'tag/v2.0.0 for the migration instructions.'
    19   )
    20 }
    21 // 对外暴露 createProvider 方法 。
    22 export function createProvider(storeKey = 'store', subKey) {
    23     const subscriptionKey = subKey || `${storeKey}Subscription`
    24 
    25     // 定义一个Provider类
    26     class Provider extends Component {
    27         getChildContext() {
    28           return { [storeKey]: this[storeKey], [subscriptionKey]: null }
    29         }
    30 
    31         constructor(props, context) {
    32           super(props, context)
    33           this[storeKey] = props.store;
    34         }
    35         // 其实就是顶层组件
    36         render() {
    37           return Children.only(this.props.children)
    38         }
    39     }
    40 
    41     if (process.env.NODE_ENV !== 'production') {
    42       Provider.prototype.componentWillReceiveProps = function (nextProps) {
    43         if (this[storeKey] !== nextProps.store) {
    44           warnAboutReceivingStore()
    45         }
    46       }
    47     }
    48 
    49     Provider.propTypes = {
    50         store: storeShape.isRequired,
    51         children: PropTypes.element.isRequired,
    52     }
    53     Provider.childContextTypes = {
    54         [storeKey]: storeShape.isRequired,
    55         [subscriptionKey]: subscriptionShape,
    56     }
    57 
    58     return Provider
    59 }
    60 
    61 // 对外暴露Provider 组件   createProvider() => Provider;
    62 export default createProvider()

    3)、connect.js

     1 import connectAdvanced from '../components/connectAdvanced'
     2 import shallowEqual from '../utils/shallowEqual'
     3 import defaultMapDispatchToPropsFactories from './mapDispatchToProps'
     4 import defaultMapStateToPropsFactories from './mapStateToProps'
     5 import defaultMergePropsFactories from './mergeProps'
     6 import defaultSelectorFactory from './selectorFactory'
     7 
     8 /*
     9   connect is a facade over connectAdvanced. It turns its args into a compatible
    10   selectorFactory, which has the signature:
    11 
    12     (dispatch, options) => (nextState, nextOwnProps) => nextFinalProps
    13   
    14   connect passes its args to connectAdvanced as options, which will in turn pass them to
    15   selectorFactory each time a Connect component instance is instantiated or hot reloaded.
    16 
    17   selectorFactory returns a final props selector from its mapStateToProps,
    18   mapStateToPropsFactories, mapDispatchToProps, mapDispatchToPropsFactories, mergeProps,
    19   mergePropsFactories, and pure args.
    20 
    21   The resulting final props selector is called by the Connect component instance whenever
    22   it receives new props or store state.
    23  */
    24 
    25 function match(arg, factories, name) {
    26   for (let i = factories.length - 1; i >= 0; i--) {
    27     const result = factories[i](arg)
    28     if (result) return result
    29   }
    30 
    31   return (dispatch, options) => {
    32     throw new Error(`Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`)
    33   }
    34 }
    35 
    36 function strictEqual(a, b) { return a === b }
    37 
    38 // createConnect with default args builds the 'official' connect behavior. Calling it with
    39 // different options opens up some testing and extensibility scenarios
    40 // 对外暴露crateConnect方法
    41 export function createConnect({
    42   connectHOC = connectAdvanced,
    43   mapStateToPropsFactories = defaultMapStateToPropsFactories,
    44   mapDispatchToPropsFactories = defaultMapDispatchToPropsFactories,
    45   mergePropsFactories = defaultMergePropsFactories,
    46   selectorFactory = defaultSelectorFactory
    47 } = {}) {
    48   // 返回一个connect函数。 接收 mapStateToProps, mapDispatchToProps, megeProps等等参数
    49   return function connect(
    50     mapStateToProps,
    51     mapDispatchToProps,
    52     mergeProps,
    53     {
    54       pure = true,
    55       areStatesEqual = strictEqual,
    56       areOwnPropsEqual = shallowEqual,
    57       areStatePropsEqual = shallowEqual,
    58       areMergedPropsEqual = shallowEqual,
    59       ...extraOptions
    60     } = {}
    61   ) {
    62     const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps')
    63     const initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps')
    64     const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps')
    65     // 调用connectHOC方法
    66     return connectHOC(selectorFactory, {
    67       // used in error messages
    68       methodName: 'connect',
    69 
    70        // used to compute Connect's displayName from the wrapped component's displayName.
    71       getDisplayName: name => `Connect(${name})`,
    72 
    73       // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes
    74       shouldHandleStateChanges: Boolean(mapStateToProps),
    75 
    76       // passed through to selectorFactory
    77       initMapStateToProps,
    78       initMapDispatchToProps,
    79       initMergeProps,
    80       pure,
    81       areStatesEqual,
    82       areOwnPropsEqual,
    83       areStatePropsEqual,
    84       areMergedPropsEqual,
    85 
    86       // any extra options args can override defaults of connect or connectAdvanced
    87       ...extraOptions
    88     })
    89   }
    90 }
    91 
    92 export default createConnect()

      

  • 相关阅读:
    CUDA从入门到精通
    [Network] 计算机网络基础知识总结
    第三章 需求工程概论
    jsp学习
    算法——递推算法
    大话设计模式读书笔记--文章汇总
    轻松学SQL Server数据库
    Oracle数据库建表+添加数据练习
    《C#图解教程》 总览
    php发送get、post请求的6种方法简明总结
  • 原文地址:https://www.cnblogs.com/createGod/p/9077618.html
Copyright © 2011-2022 走看看