Skip to content

Commit f78466f

Browse files
committed
add connectors prop to Reductor
Description: - add `connectors` property to a Reductor component that will allow it to include connectors that cannot be presented in children tree in generation of full reducer function
1 parent cf2ade6 commit f78466f

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

src/components/Reductor.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import storeShape from '../utils/storeShape';
1010
export default class Reductor extends Component {
1111
static propTypes = {
1212
createStore: PropTypes.func.isRequired,
13+
connectors: PropTypes.arrayOf(PropTypes.func),
1314
connectorProp: PropTypes.string,
1415
children: PropTypes.node.isRequired
1516
};
1617

1718
static defaultProps = {
19+
connectors: [],
1820
connectorProp: 'component'
1921
};
2022

@@ -32,15 +34,15 @@ export default class Reductor extends Component {
3234
this.store = this.props.createStore(reducer);
3335
}
3436

35-
getConnectors(childrenToProcess = this.props.children) {
37+
getChildrenConnectors(childrenToProcess = this.props.children) {
3638
const tmp = Children.map(childrenToProcess, (child) => {
3739
const connectors = [];
3840
const { [this.props.connectorProp]: component, children } = (child.props || {});
3941
if (component && component.$reducer) {
4042
connectors.push(component);
4143
}
4244
if (children) {
43-
connectors.push(...this.getConnectors(children));
45+
connectors.push(...this.getChildrenConnectors(children));
4446
}
4547
// weird thing: for some reason, when array is returned (i.e. return connectors),
4648
// React abandons all elements in it.
@@ -50,7 +52,8 @@ export default class Reductor extends Component {
5052
}
5153

5254
getReducer() {
53-
const connectors = groupBy(this.getConnectors(), '$namespace');
55+
const allConnectors = [...this.props.connectors, ...this.getChildrenConnectors()];
56+
const connectors = groupBy(allConnectors, '$namespace');
5457

5558
return function(state = {}, action) {
5659
const newState = {};

test/components/Reductor.test.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ describe('<Reductor />', function() {
2525
}));
2626
}
2727

28+
class BazConnector extends Connector {
29+
static $connection = TestConnection;
30+
static $state = {};
31+
static $reducer = BazConnector.reduce('common.baz', (state) => ({
32+
$set: (key, value) => ({ ...state, [key]: value })
33+
}));
34+
}
35+
2836
class MockRoute extends Component {
2937
static propTypes = {
3038
komponent: PropTypes.func
@@ -38,7 +46,7 @@ describe('<Reductor />', function() {
3846

3947
beforeEach(function() {
4048
this.wrapper = mount(
41-
<Reductor createStore={createStore} connectorProp="komponent">
49+
<Reductor createStore={createStore} connectors={[BazConnector]} connectorProp="komponent">
4250
<MockRoute komponent={FooConnector} />
4351
<div className="deeply-nested-connector">
4452
<MockRoute komponent={BarConnector} />
@@ -53,12 +61,16 @@ describe('<Reductor />', function() {
5361
expect(this.wrapper.contains(<div>some content</div>)).toBe(true);
5462
});
5563

56-
it('generates a reducer function based on child connectors and creates a store based on it', function() {
57-
expect(this.store.getState()).toEqual({ common: { foo: {}, bar: {} } });
64+
it('generates a reducer function based on props and child connectors and creates a store based on it', function() {
65+
expect(this.store.getState()).toEqual({ common: { foo: {}, bar: {}, baz: {} } });
5866

5967
this.store.dispatch({ type: 'common.foo/$set', args: ['text', 'A Text'] });
6068

61-
expect(this.store.getState()).toEqual({ common: { foo: { text: 'A Text' }, bar: {} } });
69+
expect(this.store.getState()).toEqual({ common: { foo: { text: 'A Text' }, bar: {}, baz: {} } });
6270
expect(this.wrapper.contains(<div>A Text</div>)).toBe(true);
71+
72+
this.store.dispatch({ type: 'common.baz/$set', args: ['text', 'Not mounted'] });
73+
74+
expect(this.store.getState()).toEqual({ common: { foo: { text: 'A Text' }, bar: {}, baz: { text: 'Not mounted' } } });
6375
});
6476
});

0 commit comments

Comments
 (0)