From bb33e65efd8b859c63bdb43c80bcd2cec330033d Mon Sep 17 00:00:00 2001 From: James Ide Date: Fri, 14 Aug 2015 03:49:49 -0700 Subject: [PATCH] Pass parent props into mapStateToProps Addresses part of #52 by passing the parent props into mapStateWithProps. --- src/components/createConnect.js | 11 +++++----- test/components/connect.spec.js | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/components/createConnect.js b/src/components/createConnect.js index 5923d7093..aa3a49e01 100644 --- a/src/components/createConnect.js +++ b/src/components/createConnect.js @@ -34,9 +34,9 @@ export default function createConnect(React) { // Helps track hot reloading. const version = nextVersion++; - function computeStateProps(store) { + function computeStateProps(store, props) { const state = store.getState(); - const stateProps = finalMapStateToProps(state); + const stateProps = finalMapStateToProps(state, props); invariant( isPlainObject(stateProps), '`mapStateToProps` must return an object. Instead received %s.', @@ -95,15 +95,15 @@ export default function createConnect(React) { `or explicitly pass "store" as a prop to "${this.constructor.displayName}".` ); - this.stateProps = computeStateProps(this.store); + this.stateProps = computeStateProps(this.store, props); this.dispatchProps = computeDispatchProps(this.store); this.state = { props: this.computeNextState() }; } - recomputeStateProps() { - const nextStateProps = computeStateProps(this.store); + recomputeStateProps(props = this.props) { + const nextStateProps = computeStateProps(this.store, props); if (shallowEqual(nextStateProps, this.stateProps)) { return false; } @@ -163,6 +163,7 @@ export default function createConnect(React) { componentWillReceiveProps(nextProps) { if (!shallowEqual(nextProps, this.props)) { + this.stateProps = computeStateProps(this.store, nextProps); this.recomputeState(nextProps); } } diff --git a/test/components/connect.spec.js b/test/components/connect.spec.js index 0e0846e5f..dfe482ad8 100644 --- a/test/components/connect.spec.js +++ b/test/components/connect.spec.js @@ -375,6 +375,45 @@ describe('React', () => { expect(div.props.stateThing).toBe('HELLO azbzcZ'); }); + it('should pass state and parent props to mapStateToProps', () => { + const store = createStore(stringBuilder); + + @connect( + (state, props) => ({idString: `[${props.id}] ${state}`}), + ) + class Container extends Component { + render() { + return
; + }; + } + + class OuterContainer extends Component { + constructor() { + super(); + this.state = {id: 0}; + } + + render() { + return ( + + {() => } + + ); + } + } + + const tree = TestUtils.renderIntoDocument(); + const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div'); + + expect(div.props.idString).toBe('[0] '); + store.dispatch({type: 'APPEND', body: 'a'}); + expect(div.props.idString).toBe('[0] a'); + tree.setState({id: 1}); + expect(div.props.idString).toBe('[1] a'); + store.dispatch({type: 'APPEND', body: 'b'}); + expect(div.props.idString).toBe('[1] ab'); + }); + it('should merge actionProps into WrappedComponent', () => { const store = createStore(() => ({ foo: 'bar'