0
votes

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?

1
I'm wondering if perhaps this is an approach that is used? stackoverflow.com/questions/36730619/…Mike Rifgin
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
@MarioTacke thanks. Makes sense.Mike Rifgin

1 Answers

2
votes

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>