Skip to content

Commit 5517ddc

Browse files
committed
Drop support for React 0.13
1 parent 499016e commit 5517ddc

13 files changed

+270
-468
lines changed

native.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"invariant": "^2.0.0"
6161
},
6262
"peerDependencies": {
63+
"react": "^0.14.0 || ^0.14.0-beta3",
6364
"redux": "^1.0.0 || 1.0.0-rc"
6465
}
6566
}

src/components/Provider.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import storeShape from '../utils/storeShape';
2+
import { Component, PropTypes, Children } from 'react';
3+
4+
export default class Provider extends Component {
5+
static childContextTypes = {
6+
store: storeShape.isRequired
7+
};
8+
9+
static propTypes = {
10+
store: storeShape.isRequired,
11+
children: PropTypes.element.isRequired
12+
};
13+
14+
getChildContext() {
15+
return { store: this.state.store };
16+
}
17+
18+
constructor(props, context) {
19+
super(props, context);
20+
this.state = { store: props.store };
21+
}
22+
23+
componentWillReceiveProps(nextProps) {
24+
const { store } = this.state;
25+
const { store: nextStore } = nextProps;
26+
27+
if (store !== nextStore) {
28+
const nextReducer = nextStore.getReducer();
29+
store.replaceReducer(nextReducer);
30+
}
31+
}
32+
33+
render() {
34+
return Children.only(this.props.children);
35+
}
36+
}

src/components/connect.js

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

src/components/createAll.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)