forked from firefox-devtools/profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
connect.js
152 lines (138 loc) · 4.2 KB
/
connect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// @flow
import * as React from 'react';
import { connect } from 'react-redux';
import type { Dispatch, State, ThunkAction, Action } from '../types/store';
type MapStateToProps<OwnProps: Object, StateProps: Object> = (
state: State,
ownProps: OwnProps
) => StateProps;
type MapDispatchToProps<OwnProps: Object, DispatchProps: Object> =
| ((dispatch: Dispatch, ownProps: OwnProps) => DispatchProps)
| DispatchProps;
type MergeProps<
StateProps,
DispatchProps: Object,
OwnProps: Object,
Props: Object
> = (
stateProps: StateProps,
dispatchProps: DispatchProps,
ownProps: OwnProps
) => Props;
type ConnectOptions = {
pure?: boolean,
areStatesEqual?: boolean,
areOwnPropsEqual?: boolean,
areStatePropsEqual?: boolean,
areMergedPropsEqual?: boolean,
storeKey?: boolean,
withRef?: boolean,
};
/**
* This function type describes the operation of taking a simple action creator, and
* just returning it.
*/
type WrapActionCreator<Args> = (
// Take as input an action creator.
(...Args) => Action
// If this function matches the above signature, do not modify it.
) => (...Args) => Action;
/**
* This function type describes the operation of removing the (Dispatch, GetState) from
* a thunk action creator.
* For instance:
* (...Args) => (Dispatch, GetState) => Returns
*
* Gets transformed into:
* (...Args) => Returns
*/
type WrapThunkActionCreator<Args, Returns> = (
// Take as input a ThunkAction.
(...Args) => ThunkAction<Returns>
// Return the wrapped action.
) => (...Args) => Returns;
/**
* This type takes a Props object and wraps each function in Redux's connect function.
* It is primarily exported for testing as explicitConnect should do this for us
* automatically. It leaves normal action creators alone, but with ThunkActions it
* removes the (Dispatch, GetState) part of a ThunkAction.
*/
export type WrapDispatchProps<DispatchProps: Object> = $ObjMap<
DispatchProps,
WrapActionCreator<*> & WrapThunkActionCreator<*, *>
>;
/**
* This type takes a single action creator, and returns the type as if the dispatch
* function was wrapped around it. It leaves normal action creators alone, but with
* ThunkActions it removes the (Dispatch, GetState) part of a ThunkAction.
*/
export type WrapFunctionInDispatch<Fn: Function> = $Call<
WrapActionCreator<*> & WrapThunkActionCreator<*, *>,
Fn
>;
export type ExplicitConnectOptions<
OwnProps: Object,
StateProps: Object,
DispatchProps: Object
> = {
mapStateToProps?: MapStateToProps<OwnProps, StateProps>,
mapDispatchToProps?: MapDispatchToProps<OwnProps, DispatchProps>,
mergeProps?: MergeProps<
StateProps,
DispatchProps,
OwnProps,
ConnectedProps<OwnProps, StateProps, DispatchProps>
>,
options?: ConnectOptions,
component: React.ComponentType<
ConnectedProps<OwnProps, StateProps, DispatchProps>
>,
};
export type ConnectedProps<
OwnProps: Object,
StateProps: Object,
DispatchProps: Object
> = $ReadOnly<{|
...OwnProps,
...StateProps,
...WrapDispatchProps<DispatchProps>,
|}>;
export type ConnectedComponent<
OwnProps: Object,
StateProps: Object,
DispatchProps: Object
> =
| React.ComponentType<ConnectedProps<OwnProps, StateProps, DispatchProps>>
| React.StatelessFunctionalComponent<
ConnectedProps<OwnProps, StateProps, DispatchProps>
>;
/**
* react-redux's connect function is too polymorphic and problematic. This function
* is a wrapper to simplify the typing of connect and make it more explicit, and
* less magical.
*/
export default function explicitConnect<
OwnProps: Object,
StateProps: Object,
DispatchProps: Object
>(
connectOptions: ExplicitConnectOptions<OwnProps, StateProps, DispatchProps>
): React.ComponentType<OwnProps> {
const {
mapStateToProps,
mapDispatchToProps,
mergeProps,
options,
component,
} = connectOptions;
// Opt out of the flow-typed definition of react-redux's connect, and use our own.
return (connect: any)(
mapStateToProps,
mapDispatchToProps,
mergeProps,
options
)(component);
}