Skip to content

Commit 7107918

Browse files
committed
feat(createPubSubConnector): Simplified 'mapSubscriptionsToProps' logic
Provided callback now receive always current props as last parameters Breaking Changes: provided callback are no longer refreshed when component props are changed
1 parent 62d4ee5 commit 7107918

File tree

2 files changed

+25
-79
lines changed

2 files changed

+25
-79
lines changed

src/components/createPubSubConnector.js

Lines changed: 11 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import isPlainObject from '../utils/isPlainObject';
44
import shallowEqual from '../utils/shallowEqual';
55
import pubSubShape from '../shapes/pubSubShape';
66

7-
const defaultRetriveProps = () => ({});
87
const defaultMapPublishToProps = publish => ({ publish });
98

109
function getDisplayName(WrappedComponent) {
@@ -62,15 +61,9 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
6261
const updateMappedSubscriptions = (key, transformerOrAlias) => {
6362
let callback;
6463
if (typeof transformerOrAlias === 'function') {
65-
const shouldUpdateSubscriptionProps = transformerOrAlias.length > 1;
66-
callback = (retrieveProps = defaultRetriveProps, silent = false) =>
67-
(...args) => {
68-
// store received values
69-
mappedSubscriptions[key].lastResult = args;
70-
mappedSubscriptions[key].shouldUpdateSubscriptionProps = shouldUpdateSubscriptionProps;
71-
64+
callback = (...args) => {
7265
// transform values
73-
const newValues = transformerOrAlias(...args, retrieveProps());
66+
const newValues = transformerOrAlias(...args, getProps());
7467

7568
if (!isPlainObject(newValues)) {
7669
throw new Error(
@@ -86,8 +79,7 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
8679
);
8780
}
8881

89-
updateSubscriptionProps(newValues, silent);
90-
return newValues;
82+
updateSubscriptionProps(newValues);
9183
};
9284
} else {
9385
callback = result => updateSubscriptionProps({ [transformerOrAlias]: result });
@@ -98,45 +90,8 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
9890

9991
mappedSubscriptions = Object.keys(subscriptionsMap)
10092
.reduce((acc, key) => {
101-
const refresh = updateMappedSubscriptions(key, subscriptionsMap[key]);
102-
let callback = refresh;
103-
if (typeof subscriptionsMap[key] === 'function') {
104-
callback = refresh(getProps);
105-
}
106-
acc[key] = {
107-
key,
108-
refresh,
109-
unsubscribe: add(key, callback),
110-
};
111-
return acc;
112-
}, {});
113-
}
114-
115-
function refreshMappedSubscriptions(subscriptionsMap = {}, getProps) {
116-
const mappedSubscriptionsKeys = Object.keys(mappedSubscriptions);
117-
if (!mappedSubscriptionsKeys.length) {
118-
return {};
119-
}
120-
121-
const silent = true;
122-
123-
return Object.keys(subscriptionsMap)
124-
.reduce((acc, key) => {
125-
if (
126-
typeof subscriptionsMap[key] === 'function'
127-
&& mappedSubscriptions[key] !== undefined
128-
) {
129-
const {
130-
refresh,
131-
lastResult,
132-
shouldUpdateSubscriptionProps,
133-
} = mappedSubscriptions[key];
134-
135-
if (shouldUpdateSubscriptionProps) {
136-
const res = refresh(getProps, silent)(...lastResult);
137-
Object.assign(acc, res);
138-
}
139-
}
93+
const callback = updateMappedSubscriptions(key, subscriptionsMap[key]);
94+
acc[key] = add(key, callback);
14095
return acc;
14196
}, {});
14297
}
@@ -156,14 +111,9 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
156111
return publishProps;
157112
}
158113

159-
function computeMappedSubscriptionProps(mappedSubscriptionProps = {}, props = {}) {
160-
const nextSubscriptionsProps = refreshMappedSubscriptions(mapSubscriptionsToProps, () => props);
161-
const merged = Object.assign({}, mappedSubscriptionProps, nextSubscriptionsProps);
162-
return cleanEmptyKeys(merged);
163-
}
164-
165114
return function wrapComponent(Composed) {
166115
class PubSubConnector extends Component {
116+
167117
constructor(props, context) {
168118
super(props, context);
169119
this.pubSubCore = props.pubSubCore || context.pubSubCore;
@@ -189,25 +139,21 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
189139
}
190140

191141
this.publishProps = computePublishProps(this.pubSub, props);
192-
this.mappedSubscriptionProps = computeMappedSubscriptionProps({}, props);
142+
this.mappedSubscriptionProps = {};
143+
193144
this.state = {};
194145
}
195146

196147
shouldComponentUpdate(nextProps, nextState) {
197148
const stateChanged = !shallowEqual(nextState, this.state);
198149
const propsChanged = !shallowEqual(nextProps, this.props);
199150
let publishPropsChanged = false;
200-
let mappedSubscriptionsPropsChanged = false;
201151

202152
if (propsChanged && shouldUpdatePublishProps) {
203153
publishPropsChanged = this.updatePublishProps(nextProps);
204154
}
205155

206-
if (propsChanged && shouldMapSubscriptions) {
207-
mappedSubscriptionsPropsChanged = this.updateMappedSubscriptions(nextProps);
208-
}
209-
210-
return propsChanged || stateChanged || publishPropsChanged || mappedSubscriptionsPropsChanged;
156+
return propsChanged || stateChanged || publishPropsChanged;
211157
}
212158

213159
componentWillUnmount() {
@@ -225,25 +171,15 @@ export default function createPubSubConnector(mapSubscriptionsToProps, mapPublis
225171
return this.refs.wrappedInstance;
226172
}
227173

228-
updateSingleMappedSubscription(updatedSubscription, silent = false) {
229-
if (!silent && updatedSubscription) {
174+
updateSingleMappedSubscription(updatedSubscription) {
175+
if (updatedSubscription) {
230176
Object.assign(this.mappedSubscriptionProps, updatedSubscription);
231177
cleanEmptyKeys(this.mappedSubscriptionProps);
232178
const lastSubscription = this.state.lastSubscription ? this.state.lastSubscription + 1 : 1;
233179
this.setState({ lastSubscription });
234180
}
235181
}
236182

237-
updateMappedSubscriptions(props = this.props) {
238-
const nextSubscriptionProps = computeMappedSubscriptionProps(this.mappedSubscriptionProps, props);
239-
if (shallowEqual(nextSubscriptionProps, this.mappedSubscriptionProps)) {
240-
return false;
241-
}
242-
243-
this.mappedSubscriptionProps = nextSubscriptionProps;
244-
return true;
245-
}
246-
247183
updatePublishProps(props = this.props) {
248184
const nextPublishProps = computePublishProps(this.pubSub, props);
249185
if (shallowEqual(nextPublishProps, this.publishProps)) {

test/components/createPubSubConnector.spec.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ test(
364364
pubSub.publish(UPDATE, { label: 'myLabel', name: 'myName' });
365365
t.is(stub.props.updatedField, 'myLabel');
366366
wrapper.setState({ updateField: 'name' });
367-
t.is(stub.props.updatedField, 'myName');
368367
pubSub.publish(UPDATE, { label: 'myLabel', name: 'myNewName' });
369368
t.is(stub.props.updatedField, 'myNewName');
370369

@@ -379,10 +378,11 @@ test(
379378
);
380379

381380
test(
382-
'should update subscriptions from `mapSubscriptionsToProps` when props changes only'
383-
+ ' if the callback defines a second arguments',
381+
'should not update subscribed actions when props changes if `mapSubscriptionsToProps`'
382+
+ ' is an object',
384383
t => {
385384
const SIMPLE_UPDATE = 'simpleUpdate';
385+
const OTHER_UPDATE = 'otherUpdate';
386386
const pubSubCore = createPubSub();
387387
const register = pubSubCore.register;
388388
let pubSub;
@@ -414,6 +414,10 @@ test(
414414
const now = new Date().getTime();
415415
return { simpleField: payload.name, now };
416416
},
417+
[OTHER_UPDATE]: (a, b) => {
418+
const otherNow = new Date().getTime();
419+
return { otherNow, a, b };
420+
},
417421
};
418422
const WrapperContainer = createPubSubConnector(mapSubscriptionsToProps)(Container);
419423

@@ -428,10 +432,16 @@ test(
428432
t.is(stub.props.simpleField, undefined);
429433
pubSub.publish(SIMPLE_UPDATE, { name: 'john' });
430434
t.is(stub.props.simpleField, 'john');
431-
const nowValue = stub.props.now;
435+
let nowValue = stub.props.now;
432436
wrapper.setState({ updateField: 'label' });
433437
t.is(stub.props.now, nowValue);
434438

439+
pubSub.publish(OTHER_UPDATE, 'yo', 'ye');
440+
t.is(stub.props.a, 'yo');
441+
nowValue = stub.props.otherNow;
442+
wrapper.setState({ updateField: 'color' });
443+
t.is(stub.props.otherNow, nowValue);
444+
435445
t.end();
436446
}
437447
);

0 commit comments

Comments
 (0)