React-router: Provide Implementation to pass props to routed components without render()

Created on 31 Jul 2017  Â·  7Comments  Â·  Source: ReactTraining/react-router

After reading all of the discussion in #4942, the resolution to use render() to pass props to route components leaves devs who hope to use the now standard react/redux with some unfortunate tradeoffs. The reality of using redux with react means that you will end up with a few top-level connected components with many dumb children. A common pattern evolves wherein router definitions generally happen in connected components, which results in extensive use of render() to pass props to dumb components.

In my current project, the component prop only gets used a few times, on the top-level routers. The bulk of my routing declarations are using render, which ends up being a lot of annoying boilerplate and very verbose routing declarations. I propose this syntax, (IE the original syntax), for passing props to routed components:

<Route component={Component} foo={bar} />

Resulting in {foo: bar} as a prop on the rendered Component. I'm sure there were good reasons for the split between component and render, but because passing props to routed components ends up being the vast majority of use cases in large projects, devs end up using the counterintuitive and verbose render() method everywhere, when the older syntax would have served better.

Most helpful comment

This has been discussed many, many, many times.

This is all you need:

<Route path="/abc" render={()=><TestWidget num="2" someProp={100}/>}/>

I'm not following your logic as to why that is an unworkable API. Perhaps an example makes that more clear. But other than looking different and involving a few more keystrokes, I don't see how it's not tenable.

All 7 comments

The main devs have stated numerous times that they do not want to expand the API by adding this (or something like it). While I personally think that it would be beneficial, I also think that it is safe to say that this isn't going to be added. You still have a few approaches that you can take.

  1. Wrap the <Route>
// this relies on you using the component prop
const RouteWithProps = ({ path, exact, strict, component:Component, location, ...rest }) => (
  <Route
    path={path}
    exact={exact}
    strict={strict}
    location={location}
    render={(props) => <Component {...props} {...rest} />}
)
// usage
<RouteWithProps component={Component} foo={bar} />
  1. Clone the <Route>

This one is more involved, but just copy the source code from here and add the ability to merge in any extra props. Maybe even release it as a package if you're feeling open sourcy.

This has been discussed many, many, many times.

This is all you need:

<Route path="/abc" render={()=><TestWidget num="2" someProp={100}/>}/>

I'm not following your logic as to why that is an unworkable API. Perhaps an example makes that more clear. But other than looking different and involving a few more keystrokes, I don't see how it's not tenable.

@pshrmn Thanks, I'll use that.

@timdorr I don't think it's unworkable or untenable, it's just sort of annoying if you have a lot of routes that require render. The reason it comes up is because a lot of the people who use the package would prefer it work that way. I've got to admit I'm puzzled as to why the maintainers are so strongly opposed.

render feature appears in 4.x. while react-router-redux only works with 3.x or former. So we should use function component currently?

@CallMeXYZ react-router-redux@next supports 4.0

@pshrmn Got stuck with wrapped Route component's path.
When using WrappedRoute

const WrappedRoute = ({ component: Component, page, ...rest }) =>
    <Route path={page.url} {...rest} render={props => <Component {...props} />} />;

all routes translates into ones without path at all (example one).
With passing path parameter in WrappedRouter, routing works as expected (example two)
What's wrong with this path?

<Route path="/abc" render={()=><TestWidget num="2" someProp={100}/>}/>

It could be helpful to have this example in a good place in the documentation. It's difficult to find the correct way to do it with the latest release, the stackoverflows comments or github's request are often a bit old.

Also, this is quite ugly but who cares…

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ackvf picture ackvf  Â·  3Comments

davetgreen picture davetgreen  Â·  3Comments

winkler1 picture winkler1  Â·  3Comments

ryansobol picture ryansobol  Â·  3Comments

andrewpillar picture andrewpillar  Â·  3Comments