Skip to content

Commit

Permalink
Pass parent props into mapStateToProps
Browse files Browse the repository at this point in the history
Addresses part of reduxjs#52 by passing the parent props into mapStateWithProps.
  • Loading branch information
ide committed Aug 14, 2015
1 parent d13d76a commit bb33e65
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
11 changes: 6 additions & 5 deletions src/components/createConnect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.',
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
39 changes: 39 additions & 0 deletions test/components/connect.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <div {...this.props}/>;
};
}

class OuterContainer extends Component {
constructor() {
super();
this.state = {id: 0};
}

render() {
return (
<Provider store={store}>
{() => <Container id={this.state.id} />}
</Provider>
);
}
}

const tree = TestUtils.renderIntoDocument(<OuterContainer />);
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'
Expand Down

0 comments on commit bb33e65

Please sign in to comment.