|
1 |
| -import React, { Component } from 'react'; |
2 |
| -import storeShape from '../utils/storeShape'; |
3 |
| -import shallowEqual from '../utils/shallowEqual'; |
4 |
| -import isPlainObject from '../utils/isPlainObject'; |
5 |
| -import wrapActionCreators from '../utils/wrapActionCreators'; |
6 |
| -import hoistStatics from 'hoist-non-react-statics'; |
7 |
| -import invariant from 'invariant'; |
8 |
| - |
9 |
| -const defaultMapStateToProps = () => ({}); |
10 |
| -const defaultMapDispatchToProps = dispatch => ({ dispatch }); |
| 1 | +import React, { Component } from 'react' |
| 2 | +import storeShape from '../utils/storeShape' |
| 3 | +import shallowEqual from '../utils/shallowEqual' |
| 4 | +import isPlainObject from '../utils/isPlainObject' |
| 5 | +import wrapActionCreators from '../utils/wrapActionCreators' |
| 6 | +import hoistStatics from 'hoist-non-react-statics' |
| 7 | +import invariant from 'invariant' |
| 8 | + |
| 9 | +const defaultMapStateToProps = () => ({}) |
| 10 | +const defaultMapDispatchToProps = dispatch => ({ dispatch }) |
11 | 11 | const defaultMergeProps = (stateProps, dispatchProps, parentProps) => ({
|
12 | 12 | ...parentProps,
|
13 | 13 | ...stateProps,
|
14 | 14 | ...dispatchProps
|
15 |
| -}); |
| 15 | +}) |
16 | 16 |
|
17 | 17 | function getDisplayName(WrappedComponent) {
|
18 |
| - return WrappedComponent.displayName || WrappedComponent.name || 'Component'; |
| 18 | + return WrappedComponent.displayName || WrappedComponent.name || 'Component' |
19 | 19 | }
|
20 | 20 |
|
21 | 21 | // Helps track hot reloading.
|
22 |
| -let nextVersion = 0; |
| 22 | +let nextVersion = 0 |
23 | 23 |
|
24 | 24 | export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
|
25 |
| - const shouldSubscribe = Boolean(mapStateToProps); |
26 |
| - const finalMapStateToProps = mapStateToProps || defaultMapStateToProps; |
| 25 | + const shouldSubscribe = Boolean(mapStateToProps) |
| 26 | + const finalMapStateToProps = mapStateToProps || defaultMapStateToProps |
27 | 27 | const finalMapDispatchToProps = isPlainObject(mapDispatchToProps) ?
|
28 | 28 | wrapActionCreators(mapDispatchToProps) :
|
29 |
| - mapDispatchToProps || defaultMapDispatchToProps; |
30 |
| - const finalMergeProps = mergeProps || defaultMergeProps; |
31 |
| - const shouldUpdateStateProps = finalMapStateToProps.length > 1; |
32 |
| - const shouldUpdateDispatchProps = finalMapDispatchToProps.length > 1; |
33 |
| - const { pure = true, withRef = false } = options; |
| 29 | + mapDispatchToProps || defaultMapDispatchToProps |
| 30 | + const finalMergeProps = mergeProps || defaultMergeProps |
| 31 | + const shouldUpdateStateProps = finalMapStateToProps.length > 1 |
| 32 | + const shouldUpdateDispatchProps = finalMapDispatchToProps.length > 1 |
| 33 | + const { pure = true, withRef = false } = options |
34 | 34 |
|
35 | 35 | // Helps track hot reloading.
|
36 |
| - const version = nextVersion++; |
| 36 | + const version = nextVersion++ |
37 | 37 |
|
38 | 38 | function computeStateProps(store, props) {
|
39 |
| - const state = store.getState(); |
| 39 | + const state = store.getState() |
40 | 40 | const stateProps = shouldUpdateStateProps ?
|
41 | 41 | finalMapStateToProps(state, props) :
|
42 |
| - finalMapStateToProps(state); |
| 42 | + finalMapStateToProps(state) |
43 | 43 |
|
44 | 44 | invariant(
|
45 | 45 | isPlainObject(stateProps),
|
46 | 46 | '`mapStateToProps` must return an object. Instead received %s.',
|
47 | 47 | stateProps
|
48 |
| - ); |
49 |
| - return stateProps; |
| 48 | + ) |
| 49 | + return stateProps |
50 | 50 | }
|
51 | 51 |
|
52 | 52 | function computeDispatchProps(store, props) {
|
53 |
| - const { dispatch } = store; |
| 53 | + const { dispatch } = store |
54 | 54 | const dispatchProps = shouldUpdateDispatchProps ?
|
55 | 55 | finalMapDispatchToProps(dispatch, props) :
|
56 |
| - finalMapDispatchToProps(dispatch); |
| 56 | + finalMapDispatchToProps(dispatch) |
57 | 57 |
|
58 | 58 | invariant(
|
59 | 59 | isPlainObject(dispatchProps),
|
60 | 60 | '`mapDispatchToProps` must return an object. Instead received %s.',
|
61 | 61 | dispatchProps
|
62 |
| - ); |
63 |
| - return dispatchProps; |
| 62 | + ) |
| 63 | + return dispatchProps |
64 | 64 | }
|
65 | 65 |
|
66 | 66 | function computeNextState(stateProps, dispatchProps, parentProps) {
|
67 |
| - const mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps); |
| 67 | + const mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps) |
68 | 68 | invariant(
|
69 | 69 | isPlainObject(mergedProps),
|
70 | 70 | '`mergeProps` must return an object. Instead received %s.',
|
71 | 71 | mergedProps
|
72 |
| - ); |
73 |
| - return mergedProps; |
| 72 | + ) |
| 73 | + return mergedProps |
74 | 74 | }
|
75 | 75 |
|
76 | 76 | return function wrapWithConnect(WrappedComponent) {
|
77 | 77 | class Connect extends Component {
|
78 | 78 | shouldComponentUpdate(nextProps, nextState) {
|
79 | 79 | if (!pure) {
|
80 |
| - this.updateStateProps(nextProps); |
81 |
| - this.updateDispatchProps(nextProps); |
82 |
| - this.updateState(nextProps); |
83 |
| - return true; |
| 80 | + this.updateStateProps(nextProps) |
| 81 | + this.updateDispatchProps(nextProps) |
| 82 | + this.updateState(nextProps) |
| 83 | + return true |
84 | 84 | }
|
85 | 85 |
|
86 |
| - const storeChanged = nextState.storeState !== this.state.storeState; |
87 |
| - const propsChanged = !shallowEqual(nextProps, this.props); |
88 |
| - let mapStateProducedChange = false; |
89 |
| - let dispatchPropsChanged = false; |
| 86 | + const storeChanged = nextState.storeState !== this.state.storeState |
| 87 | + const propsChanged = !shallowEqual(nextProps, this.props) |
| 88 | + let mapStateProducedChange = false |
| 89 | + let dispatchPropsChanged = false |
90 | 90 |
|
91 | 91 | if (storeChanged || (propsChanged && shouldUpdateStateProps)) {
|
92 |
| - mapStateProducedChange = this.updateStateProps(nextProps); |
| 92 | + mapStateProducedChange = this.updateStateProps(nextProps) |
93 | 93 | }
|
94 | 94 |
|
95 | 95 | if (propsChanged && shouldUpdateDispatchProps) {
|
96 |
| - dispatchPropsChanged = this.updateDispatchProps(nextProps); |
| 96 | + dispatchPropsChanged = this.updateDispatchProps(nextProps) |
97 | 97 | }
|
98 | 98 |
|
99 | 99 | if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
|
100 |
| - this.updateState(nextProps); |
101 |
| - return true; |
| 100 | + this.updateState(nextProps) |
| 101 | + return true |
102 | 102 | }
|
103 | 103 |
|
104 |
| - return false; |
| 104 | + return false |
105 | 105 | }
|
106 | 106 |
|
107 | 107 | constructor(props, context) {
|
108 |
| - super(props, context); |
109 |
| - this.version = version; |
110 |
| - this.store = props.store || context.store; |
| 108 | + super(props, context) |
| 109 | + this.version = version |
| 110 | + this.store = props.store || context.store |
111 | 111 |
|
112 | 112 | invariant(this.store,
|
113 | 113 | `Could not find "store" in either the context or ` +
|
114 | 114 | `props of "${this.constructor.displayName}". ` +
|
115 | 115 | `Either wrap the root component in a <Provider>, ` +
|
116 | 116 | `or explicitly pass "store" as a prop to "${this.constructor.displayName}".`
|
117 |
| - ); |
| 117 | + ) |
118 | 118 |
|
119 |
| - this.stateProps = computeStateProps(this.store, props); |
120 |
| - this.dispatchProps = computeDispatchProps(this.store, props); |
121 |
| - this.state = { storeState: null }; |
122 |
| - this.updateState(); |
| 119 | + this.stateProps = computeStateProps(this.store, props) |
| 120 | + this.dispatchProps = computeDispatchProps(this.store, props) |
| 121 | + this.state = { storeState: null } |
| 122 | + this.updateState() |
123 | 123 | }
|
124 | 124 |
|
125 | 125 | computeNextState(props = this.props) {
|
126 | 126 | return computeNextState(
|
127 | 127 | this.stateProps,
|
128 | 128 | this.dispatchProps,
|
129 | 129 | props
|
130 |
| - ); |
| 130 | + ) |
131 | 131 | }
|
132 | 132 |
|
133 | 133 | updateStateProps(props = this.props) {
|
134 |
| - const nextStateProps = computeStateProps(this.store, props); |
| 134 | + const nextStateProps = computeStateProps(this.store, props) |
135 | 135 | if (shallowEqual(nextStateProps, this.stateProps)) {
|
136 |
| - return false; |
| 136 | + return false |
137 | 137 | }
|
138 | 138 |
|
139 |
| - this.stateProps = nextStateProps; |
140 |
| - return true; |
| 139 | + this.stateProps = nextStateProps |
| 140 | + return true |
141 | 141 | }
|
142 | 142 |
|
143 | 143 | updateDispatchProps(props = this.props) {
|
144 |
| - const nextDispatchProps = computeDispatchProps(this.store, props); |
| 144 | + const nextDispatchProps = computeDispatchProps(this.store, props) |
145 | 145 | if (shallowEqual(nextDispatchProps, this.dispatchProps)) {
|
146 |
| - return false; |
| 146 | + return false |
147 | 147 | }
|
148 | 148 |
|
149 |
| - this.dispatchProps = nextDispatchProps; |
150 |
| - return true; |
| 149 | + this.dispatchProps = nextDispatchProps |
| 150 | + return true |
151 | 151 | }
|
152 | 152 |
|
153 | 153 | updateState(props = this.props) {
|
154 |
| - this.nextState = this.computeNextState(props); |
| 154 | + this.nextState = this.computeNextState(props) |
155 | 155 | }
|
156 | 156 |
|
157 | 157 | isSubscribed() {
|
158 |
| - return typeof this.unsubscribe === 'function'; |
| 158 | + return typeof this.unsubscribe === 'function' |
159 | 159 | }
|
160 | 160 |
|
161 | 161 | trySubscribe() {
|
162 | 162 | if (shouldSubscribe && !this.unsubscribe) {
|
163 |
| - this.unsubscribe = this.store.subscribe(::this.handleChange); |
164 |
| - this.handleChange(); |
| 163 | + this.unsubscribe = this.store.subscribe(::this.handleChange) |
| 164 | + this.handleChange() |
165 | 165 | }
|
166 | 166 | }
|
167 | 167 |
|
168 | 168 | tryUnsubscribe() {
|
169 | 169 | if (this.unsubscribe) {
|
170 |
| - this.unsubscribe(); |
171 |
| - this.unsubscribe = null; |
| 170 | + this.unsubscribe() |
| 171 | + this.unsubscribe = null |
172 | 172 | }
|
173 | 173 | }
|
174 | 174 |
|
175 | 175 | componentDidMount() {
|
176 |
| - this.trySubscribe(); |
| 176 | + this.trySubscribe() |
177 | 177 | }
|
178 | 178 |
|
179 | 179 | componentWillUnmount() {
|
180 |
| - this.tryUnsubscribe(); |
| 180 | + this.tryUnsubscribe() |
181 | 181 | }
|
182 | 182 |
|
183 | 183 | handleChange() {
|
184 | 184 | if (!this.unsubscribe) {
|
185 |
| - return; |
| 185 | + return |
186 | 186 | }
|
187 | 187 |
|
188 | 188 | this.setState({
|
189 | 189 | storeState: this.store.getState()
|
190 |
| - }); |
| 190 | + }) |
191 | 191 | }
|
192 | 192 |
|
193 | 193 | getWrappedInstance() {
|
194 | 194 | invariant(withRef,
|
195 | 195 | `To access the wrapped instance, you need to specify ` +
|
196 | 196 | `{ withRef: true } as the fourth argument of the connect() call.`
|
197 |
| - ); |
| 197 | + ) |
198 | 198 |
|
199 |
| - return this.refs.wrappedInstance; |
| 199 | + return this.refs.wrappedInstance |
200 | 200 | }
|
201 | 201 |
|
202 | 202 | render() {
|
203 |
| - const ref = withRef ? 'wrappedInstance' : null; |
| 203 | + const ref = withRef ? 'wrappedInstance' : null |
204 | 204 | return (
|
205 | 205 | <WrappedComponent {...this.nextState} ref={ref} />
|
206 |
| - ); |
| 206 | + ) |
207 | 207 | }
|
208 | 208 | }
|
209 | 209 |
|
210 |
| - Connect.displayName = `Connect(${getDisplayName(WrappedComponent)})`; |
211 |
| - Connect.WrappedComponent = WrappedComponent; |
| 210 | + Connect.displayName = `Connect(${getDisplayName(WrappedComponent)})` |
| 211 | + Connect.WrappedComponent = WrappedComponent |
212 | 212 | Connect.contextTypes = {
|
213 | 213 | store: storeShape
|
214 |
| - }; |
| 214 | + } |
215 | 215 | Connect.propTypes = {
|
216 | 216 | store: storeShape
|
217 |
| - }; |
| 217 | + } |
218 | 218 |
|
219 | 219 | if (process.env.NODE_ENV !== 'production') {
|
220 | 220 | Connect.prototype.componentWillUpdate = function componentWillUpdate() {
|
221 | 221 | if (this.version === version) {
|
222 |
| - return; |
| 222 | + return |
223 | 223 | }
|
224 | 224 |
|
225 | 225 | // We are hot reloading!
|
226 |
| - this.version = version; |
| 226 | + this.version = version |
227 | 227 |
|
228 | 228 | // Update the state and bindings.
|
229 |
| - this.trySubscribe(); |
230 |
| - this.updateStateProps(); |
231 |
| - this.updateDispatchProps(); |
232 |
| - this.updateState(); |
233 |
| - }; |
| 229 | + this.trySubscribe() |
| 230 | + this.updateStateProps() |
| 231 | + this.updateDispatchProps() |
| 232 | + this.updateState() |
| 233 | + } |
234 | 234 | }
|
235 | 235 |
|
236 |
| - return hoistStatics(Connect, WrappedComponent); |
237 |
| - }; |
| 236 | + return hoistStatics(Connect, WrappedComponent) |
| 237 | + } |
238 | 238 | }
|
0 commit comments