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+ function match ( arg , factories , name ) {
9+ for ( let i = factories . length - 1 ; i >= 0 ; i -- ) {
10+ const result = factories [ i ] ( arg )
11+ if ( result ) return result
12+ }
13+ return ( dispatch , options ) => {
14+ throw new Error ( `Invalid value of type ${ typeof arg } for ${ name } argument when connecting component ${ options . wrappedComponentName } .` )
15+ }
16+ }
17+
18+ function strictEqual ( a , b ) { return a === b }
19+
20+ // createConnect with default args builds the 'official' connect behavior. Calling it with
21+ // different options opens up some testing and extensibility scenarios
22+ export function createConnect ( {
23+ connectHOC = connectAdvanced ,
24+ mapStateToPropsFactories = defaultMapStateToPropsFactories ,
25+ mapDispatchToPropsFactories = defaultMapDispatchToPropsFactories ,
26+ mergePropsFactories = defaultMergePropsFactories ,
27+ selectorFactory = defaultSelectorFactory
28+ } = { } ) {
29+ return function connect (
30+ mapStateToProps ,
31+ mapDispatchToProps ,
32+ mergeProps ,
33+ {
34+ pure = true ,
35+ areStatesEqual = strictEqual ,
36+ areOwnPropsEqual = shallowEqual ,
37+ areStatePropsEqual = shallowEqual ,
38+ areMergedPropsEqual = shallowEqual ,
39+ ...extraOptions
40+ } = { }
41+ ) {
42+ const initMapStateToProps = match ( mapStateToProps , mapStateToPropsFactories , 'mapStateToProps' )
43+ const initMapDispatchToProps = match ( mapDispatchToProps , mapDispatchToPropsFactories , 'mapDispatchToProps' )
44+ const initMergeProps = match ( mergeProps , mergePropsFactories , 'mergeProps' )
45+ return connectHOC ( selectorFactory , {
46+ // used in error messages
47+ methodName : 'connect' ,
48+ // used to compute Connect's displayName from the wrapped component's displayName.
49+ getDisplayName : name => `Connect(${ name } )` ,
50+ // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes
51+ shouldHandleStateChanges : Boolean ( mapStateToProps ) ,
52+ // passed through to selectorFactory
53+ initMapStateToProps,
54+ initMapDispatchToProps,
55+ initMergeProps,
56+ pure,
57+ areStatesEqual,
58+ areOwnPropsEqual,
59+ areStatePropsEqual,
60+ areMergedPropsEqual,
61+ // any extra options args can override defaults of connect or connectAdvanced
62+ ...extraOptions
63+ } )
64+ }
65+ }
66+
67+ export default createConnect ( )
0 commit comments