Skip to content

Commit 284d6f7

Browse files
committed
Merge pull request #122 from epeli/impurefix
Call map functions for impure components
2 parents 607dc96 + 8bc405d commit 284d6f7

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/components/createConnect.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export default function createConnect(React) {
9090

9191
shouldComponentUpdate(nextProps, nextState) {
9292
if (!pure) {
93+
this.updateStateProps(nextProps);
94+
this.updateDispatchProps(nextProps);
9395
this.updateState(nextProps);
9496
return true;
9597
}

test/components/connect.spec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,65 @@ describe('React', () => {
11481148
expect(target.props.statefulValue).toEqual(1);
11491149
});
11501150

1151+
it('calls mapState and mapDispatch for impure components', () => {
1152+
const store = createStore(() => ({
1153+
foo: 'foo',
1154+
bar: 'bar'
1155+
}));
1156+
1157+
const mapStateSpy = expect.createSpy();
1158+
const mapDispatchSpy = expect.createSpy().andReturn({});
1159+
1160+
class ImpureComponent extends Component {
1161+
render() {
1162+
return <Passthrough statefulValue={this.props.value} />;
1163+
}
1164+
}
1165+
1166+
const decorator = connect(
1167+
(state, {storeGetter}) => {
1168+
mapStateSpy();
1169+
return {value: state[storeGetter.storeKey]};
1170+
},
1171+
mapDispatchSpy,
1172+
null,
1173+
{ pure: false }
1174+
);
1175+
const Decorated = decorator(ImpureComponent);
1176+
1177+
class StatefulWrapper extends Component {
1178+
state = {
1179+
storeGetter: {storeKey: 'foo'}
1180+
};
1181+
1182+
render() {
1183+
return <Decorated storeGetter={this.state.storeGetter} />;
1184+
};
1185+
}
1186+
1187+
const tree = TestUtils.renderIntoDocument(
1188+
<ProviderMock store={store}>
1189+
<StatefulWrapper />
1190+
</ProviderMock>
1191+
);
1192+
1193+
const target = TestUtils.findRenderedComponentWithType(tree, Passthrough);
1194+
const wrapper = TestUtils.findRenderedComponentWithType(tree, StatefulWrapper);
1195+
1196+
expect(mapStateSpy.calls.length).toBe(2);
1197+
expect(mapDispatchSpy.calls.length).toBe(2);
1198+
expect(target.props.statefulValue).toEqual('foo');
1199+
1200+
// Impure update
1201+
const storeGetter = wrapper.state.storeGetter;
1202+
storeGetter.storeKey = 'bar';
1203+
wrapper.setState({ storeGetter });
1204+
1205+
expect(mapStateSpy.calls.length).toBe(3);
1206+
expect(mapDispatchSpy.calls.length).toBe(3);
1207+
expect(target.props.statefulValue).toEqual('bar');
1208+
});
1209+
11511210
it('should pass state consistently to mapState', () => {
11521211
const store = createStore(stringBuilder);
11531212

0 commit comments

Comments
 (0)