|
- import connectAdvanced from '../components/connectAdvanced'
- import shallowEqual from '../utils/shallowEqual'
- import defaultMapDispatchToPropsFactories from './mapDispatchToProps'
- import defaultMapStateToPropsFactories from './mapStateToProps'
- import defaultMergePropsFactories from './mergeProps'
- import defaultSelectorFactory from './selectorFactory'
-
- /*
- connect is a facade over connectAdvanced. It turns its args into a compatible
- selectorFactory, which has the signature:
-
- (dispatch, options) => (nextState, nextOwnProps) => nextFinalProps
-
- connect passes its args to connectAdvanced as options, which will in turn pass them to
- selectorFactory each time a Connect component instance is instantiated or hot reloaded.
-
- selectorFactory returns a final props selector from its mapStateToProps,
- mapStateToPropsFactories, mapDispatchToProps, mapDispatchToPropsFactories, mergeProps,
- mergePropsFactories, and pure args.
-
- The resulting final props selector is called by the Connect component instance whenever
- it receives new props or store state.
- */
-
- function match(arg, factories, name) {
- for (let i = factories.length - 1; i >= 0; i--) {
- const result = factories[i](arg)
- if (result) return result
- }
-
- return (dispatch, options) => {
- throw new Error(
- `Invalid value of type ${typeof arg} for ${name} argument when connecting component ${
- options.wrappedComponentName
- }.`
- )
- }
- }
-
- function strictEqual(a, b) {
- return a === b
- }
-
- // createConnect with default args builds the 'official' connect behavior. Calling it with
- // different options opens up some testing and extensibility scenarios
- export function createConnect({
- connectHOC = connectAdvanced,
- mapStateToPropsFactories = defaultMapStateToPropsFactories,
- mapDispatchToPropsFactories = defaultMapDispatchToPropsFactories,
- mergePropsFactories = defaultMergePropsFactories,
- selectorFactory = defaultSelectorFactory
- } = {}) {
- return function connect(
- mapStateToProps,
- mapDispatchToProps,
- mergeProps,
- {
- pure = true,
- areStatesEqual = strictEqual,
- areOwnPropsEqual = shallowEqual,
- areStatePropsEqual = shallowEqual,
- areMergedPropsEqual = shallowEqual,
- ...extraOptions
- } = {}
- ) {
- const initMapStateToProps = match(
- mapStateToProps,
- mapStateToPropsFactories,
- 'mapStateToProps'
- )
- const initMapDispatchToProps = match(
- mapDispatchToProps,
- mapDispatchToPropsFactories,
- 'mapDispatchToProps'
- )
- const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps')
-
- return connectHOC(selectorFactory, {
- // used in error messages
- methodName: 'connect',
-
- // used to compute Connect's displayName from the wrapped component's displayName.
- getDisplayName: name => `Connect(${name})`,
-
- // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes
- shouldHandleStateChanges: Boolean(mapStateToProps),
-
- // passed through to selectorFactory
- initMapStateToProps,
- initMapDispatchToProps,
- initMergeProps,
- pure,
- areStatesEqual,
- areOwnPropsEqual,
- areStatePropsEqual,
- areMergedPropsEqual,
-
- // any extra options args can override defaults of connect or connectAdvanced
- ...extraOptions
- })
- }
- }
-
- export default /*#__PURE__*/ createConnect()
|