Skip to content

Commit a563264

Browse files
committed
Merge branch 'leoasis-react_native_support'
2 parents 6aa4431 + c6ecdbc commit a563264

18 files changed

+200
-168
lines changed

examples/containers/App.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
22
import CounterApp from './CounterApp';
33
import TodoApp from './TodoApp';
4-
import { createRedux, Provider } from 'redux';
4+
import { createRedux } from 'redux';
5+
import { Provider } from 'redux/react';
56
import * as stores from '../stores';
67

78
const redux = createRedux(stores);

examples/containers/CounterApp.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { connect, bindActionCreators } from 'redux';
2+
import { bindActionCreators } from 'redux';
3+
import { connect } from 'redux/react';
34
import Counter from '../components/Counter';
45
import * as CounterActions from '../actions/CounterActions';
56

examples/containers/TodoApp.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { bindActionCreators, Connector } from 'redux';
2+
import { bindActionCreators } from 'redux';
3+
import { Connector } from 'redux/react';
34
import AddTodo from '../components/AddTodo';
45
import TodoList from '../components/TodoList';
56
import * as TodoActions from '../actions/TodoActions';

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"eslint-plugin-react": "^2.3.0",
4343
"expect": "^1.6.0",
4444
"mocha": "^2.2.5",
45+
"react": "^0.13.0",
4546
"react-hot-loader": "^1.2.7",
4647
"rimraf": "^2.3.4",
4748
"webpack": "^1.9.6",
@@ -51,8 +52,7 @@
5152
"babel-runtime": "^5.4.7",
5253
"envify": "^3.4.0",
5354
"invariant": "^2.0.0",
54-
"lodash": "^3.9.3",
55-
"react": "^0.13.0"
55+
"lodash": "^3.9.3"
5656
},
5757
"browserify": {
5858
"transform": [

react-native.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/react-native';

react.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/react';

src/components/Connector.js

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

src/components/Provider.js

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

src/components/connect.js

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

src/components/createAll.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import createProvider from './createProvider';
2+
import createProvideDecorator from './createProvideDecorator';
3+
4+
import createConnector from './createConnector';
5+
import createConnectDecorator from './createConnectDecorator';
6+
7+
export default function createAll(React) {
8+
// Wrapper components
9+
const Provider = createProvider(React);
10+
const Connector = createConnector(React);
11+
12+
// Higher-order components (decorators)
13+
const provide = createProvideDecorator(React, Provider);
14+
const connect = createConnectDecorator(React, Connector);
15+
16+
return { Provider, Connector, provide, connect };
17+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import getDisplayName from '../utils/getDisplayName';
2+
import shallowEqualScalar from '../utils/shallowEqualScalar';
3+
4+
export default function createConnectDecorator(React, Connector) {
5+
return function connect(select) {
6+
return DecoratedComponent => class ConnectorDecorator {
7+
static displayName = `Connector(${getDisplayName(DecoratedComponent)})`;
8+
9+
shouldComponentUpdate(nextProps) {
10+
return !shallowEqualScalar(this.props, nextProps);
11+
}
12+
13+
render() {
14+
return (
15+
<Connector select={state => select(state, this.props)}>
16+
{this.renderChild}
17+
</Connector>
18+
);
19+
}
20+
21+
renderChild(state) {
22+
return <DecoratedComponent {...state} />;
23+
}
24+
};
25+
};
26+
}

src/components/createConnector.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import identity from 'lodash/utility/identity';
2+
import shallowEqual from '../utils/shallowEqual';
3+
4+
export default function createConnector(React) {
5+
6+
const { Component, PropTypes } = React;
7+
8+
return class Connector extends Component {
9+
static contextTypes = {
10+
redux: PropTypes.object.isRequired
11+
};
12+
13+
static propTypes = {
14+
children: PropTypes.func.isRequired,
15+
select: PropTypes.func.isRequired
16+
};
17+
18+
static defaultProps = {
19+
select: identity
20+
};
21+
22+
shouldComponentUpdate(nextProps, nextState) {
23+
return !this.isSliceEqual(this.state.slice, nextState.slice) ||
24+
!shallowEqual(this.props, nextProps);
25+
}
26+
27+
isSliceEqual(slice, nextSlice) {
28+
const isRefEqual = slice === nextSlice;
29+
if (isRefEqual) {
30+
return true;
31+
} else if (typeof slice !== 'object' || typeof nextSlice !== 'object') {
32+
return isRefEqual;
33+
} else {
34+
return shallowEqual(slice, nextSlice);
35+
}
36+
}
37+
38+
constructor(props, context) {
39+
super(props, context);
40+
41+
this.handleChange = this.handleChange.bind(this);
42+
this.unsubscribe = context.redux.subscribe(this.handleChange);
43+
this.handleChange();
44+
}
45+
46+
componentWillReceiveProps(nextProps) {
47+
if (nextProps.select !== this.props.select) {
48+
// Force the state slice recalculation
49+
this.handleChange();
50+
}
51+
}
52+
53+
componentWillUnmount() {
54+
this.unsubscribe();
55+
}
56+
57+
handleChange() {
58+
const state = this.context.redux.getState();
59+
const slice = this.props.select(state);
60+
61+
if (this.state) {
62+
this.setState({ slice });
63+
} else {
64+
this.state = { slice };
65+
}
66+
}
67+
68+
render() {
69+
const { children } = this.props;
70+
const { slice } = this.state;
71+
const { redux } = this.context;
72+
73+
return children({
74+
dispatch: ::redux.dispatch,
75+
...slice
76+
});
77+
}
78+
};
79+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import getDisplayName from '../utils/getDisplayName';
2+
3+
export default function createProvideDecorator(React, Provider) {
4+
return function provide(redux) {
5+
return DecoratedComponent => class ProviderDecorator {
6+
static displayName = `Provider(${getDisplayName(DecoratedComponent)})`;
7+
8+
render() {
9+
return (
10+
<Provider redux={redux}>
11+
{props => <DecoratedComponent {...this.props} {...props} />}
12+
</Provider>
13+
);
14+
}
15+
};
16+
};
17+
}

src/components/createProvider.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export default function createProvider(React) {
2+
const { Component, PropTypes } = React;
3+
4+
const reduxShape = PropTypes.shape({
5+
subscribe: PropTypes.func.isRequired,
6+
dispatch: PropTypes.func.isRequired,
7+
getState: PropTypes.func.isRequired
8+
});
9+
10+
return class Provider extends Component {
11+
static propTypes = {
12+
redux: reduxShape.isRequired,
13+
children: PropTypes.func.isRequired
14+
};
15+
16+
static childContextTypes = {
17+
redux: reduxShape.isRequired
18+
};
19+
20+
getChildContext() {
21+
return { redux: this.state.redux };
22+
}
23+
24+
constructor(props, context) {
25+
super(props, context);
26+
this.state = { redux: props.redux };
27+
}
28+
29+
componentWillReceiveProps(nextProps) {
30+
const nextDispatcher = nextProps.redux.getDispatcher();
31+
this.state.redux.replaceDispatcher(nextDispatcher);
32+
}
33+
34+
render() {
35+
const { children } = this.props;
36+
return children();
37+
}
38+
};
39+
}

src/components/provide.js

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

0 commit comments

Comments
 (0)