0

I have an App component that is connected to a redux store:

import React from 'react'
import { connect } from 'react-redux'

function App(props) {
  return (
    <div>
      {props.children}
    </div>
  );
}

function mapStateToProps(state) {
  return { 
    todos: state.something
  }
}

export default connect(mapStateToProps)(App)

App is the root level component in my react router hierarchy and so receives all child routes as children:

export default(
  <Route component={App} path="/">
    <IndexRoute component={Home} />
    <Route component={PageNotFound} path="*" />
  </Route>
);

I want to be able to pass the props that are passed in to App via mapStateToProps to child components. It seems the accepted way to do this is to use cloneElement to allow props to be passed to children (How to pass props to {this.props.children}). So the code in the first snippet above:

<div>
  {props.children}
</div>

becomes:

<div>
  {React.cloneElement(props.children, { ...props }
</div>

I find this rather ugly because it means I am blindly passing all props from my connected app component in to my children route components.

Is this really the accepted way of doing this?

Community
  • 1
  • 1
Mike Rifgin
  • 10,409
  • 21
  • 75
  • 111
  • I'm wondering if perhaps this is an approach that is used? http://stackoverflow.com/questions/36730619/unable-to-pass-redux-store-beyond-react-router/39300618#39300618 – Mike Rifgin Sep 20 '16 at 19:01
  • 1
    If you don't want all props "blindly" passed down, you could `connect` your `Home` or other components like you did with your `App` component and have a different `mapStateToProps` function in each. – Mario Tacke Sep 20 '16 at 19:55
  • @MarioTacke thanks. Makes sense. – Mike Rifgin Sep 21 '16 at 07:31

1 Answers1

2

If you know what props were created in mapStateToProps, you can extract and pass further only them.

Also, it might be helpful, if you return a single prop with all necessary data from mapStateToProps, let's name it componentState:

function mapStateToProps({todos, somethingElse}) {
  return {
    componentState: { todos, somethingElse }
  }
}

Then later you can pass only this single prop down

<div>
  {React.cloneElement(props.children, { componentState: this.props.componentState }
</div>
just-boris
  • 9,468
  • 5
  • 48
  • 84
  • Yes that's a good approach. Ended up going with each route component being a connected container with a mapStateToProps. – Mike Rifgin Sep 21 '16 at 07:32