Passing props to react-redux container component

ReactjsReact NativeReduxReact Redux

Reactjs Problem Overview


I have a react-redux container component that is created within a React Native Navigator component. I want to be able to pass the navigator as a prop to this container component so that after a button is pressed inside its presentational component, it can push an object onto the navigator stack.

I want to do this without needing to hand write all the boilerplate code that the react-redux container component gives me (and also not miss out on all the optimisations that react-redux would give me here too).

Example container component code:

const mapStateToProps = (state) => {
    return {
        prop1: state.prop1,
        prop2: state.prop2
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        onSearchPressed: (e) => {
            dispatch(submitSearch(navigator)) // This is where I want to use the injected navigator
        }
    }
}

const SearchViewContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(SearchView)

export default SearchViewContainer

And I'd want to be able to call the component like this from within my navigator renderScene function:

<SearchViewContainer navigator={navigator}/>

In the container code above, I'd need to be able to access this passed prop from within the mapDispatchToProps function.

I don't fancy storing the navigator on the redux state object and don't want to pass the prop down to the presentational component.

Is there a way I can pass in a prop to this container component? Alternatively, are there any alternative approaches that I'm overlooking?

Thanks.

Reactjs Solutions


Solution 1 - Reactjs

mapStateToProps and mapDispatchToProps both take ownProps as the second argument.

[mapStateToProps(state, [ownProps]): stateProps] (Function):
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function):

For reference

Solution 2 - Reactjs

You can pass in a second argument to mapStateToProps(state, ownProps) which will give you access to the props passed into the component in mapStateToProps

Solution 3 - Reactjs

There's a few gotchas when doing this with typescript, so here's an example.

One gotcha was when you are only using dispatchToProps (and not mapping any state props), it's important to not omit the state param, (it can be named with an underscore prefix).

Another gotcha was that the ownProps param had to be typed using an interface containing only the passed props - this can be achieved by splitting your props interface into two interfaces, e.g.

interface MyComponentOwnProps {
  value: number;
}

interface MyComponentConnectedProps {
  someAction: (x: number) => void;
}

export class MyComponent extends React.Component<
  MyComponentOwnProps & MyComponentConnectedProps
> {
....//  component logic
}

const mapStateToProps = (
  _state: AppState,
  ownProps: MyComponentOwnProps,
) => ({
  value: ownProps.value,
});

const mapDispatchToProps = {
  someAction,
};

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

The component can be declared by passing the single parameter:

<MyComponent value={event} />

Solution 4 - Reactjs

Using Decorators (@)

If you are using decorators, the code below give an example in the case you want to use decorators for your redux connect.

@connect(
	(state, ownProps) => {
		return {
			Foo: ownProps.Foo,
		}
	}
)
export default class Bar extends React.Component {

If you now check this.props.Foo you will see the prop that was added from where the Bar component was used.

<Bar Foo={'Baz'} />

In this case this.props.Foo will be the string 'Baz'

Hope this clarifies some things.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeView Question on Stackoverflow
Solution 1 - ReactjsAbhinav SingiView Answer on Stackoverflow
Solution 2 - ReactjsConor HastingsView Answer on Stackoverflow
Solution 3 - ReactjsDamian GreenView Answer on Stackoverflow
Solution 4 - ReactjsJoe LloydView Answer on Stackoverflow