Tee F
Tee F

Reputation: 285

Pass props through route

In react how can I configure a route to pass props. for example my route.tsx is:

export const routes = () => (
  <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={ FetchData } />
  </Layout>
);

How can I pass some data as props to my Counter component when ever /counter is evoked

Upvotes: 8

Views: 7523

Answers (4)

user1034533
user1034533

Reputation: 1074

As noted in other answers, this is handled by the render prop, which gives the example:

<Route path="/home" render={() => <div>Home</div>}/>

However, I (and many others) find this syntax pretty ugly. In the original issue on prop passing with Route, there's a well-liked wrapper which I wanted to surface, I've made some improvements and propose this terse and effective wrapper:

const PropsRoute = ({component, path, ...otherProps}) => (
  <Route {...otherProps} path={path} render={routeProps => 
      React.createElement(component, {...otherProps, ...routeProps})
    } />
)     

This can be used as might be expected:

<Router>
   <main>
     <PropsRoute exact path="/" component={Home} auth={this.state.auth} />
   </main>
</router>

Note that doing this will pass the Route props down to the component. Any prop passed to Route that isn't 'component' or 'path' will be passed down to the component. In this formulation, any routeProps (passed by the react-router) will override custom props passed via this syntax.

This can then be quite easily expanded on to make the common login pattern:

const AuthedRoute = ({auth, ...props}) =>
  !auth.valid()? <Redirect to="/login" />: <PropsRoute {...{...props, auth: auth}} />;

Edit: I've largely abandoned this approach as of 2019, in favour of something like this:

<Route {...{
    path: "/path/to/component",
    render: ({ location }) => <MyComponent {...{
        location
    }}/>
}}/>

This can appear a bit more gnarly, but it makes deeply nested render trees much clearer, and lets you use full Javascript in your JSX parameters.

Upvotes: 1

Omar
Omar

Reputation: 3411

You can use the render prop.

  <Route 
     path='/counter' 
     render={(props) => (
       <Counter {...props} count={5} />
     )} 
  />

Upvotes: 12

Ferus
Ferus

Reputation: 1118

To simplify things you could create a wrapper around <Route>:

const RouteWrapper = ({ children, ...props }) => {
    const childrenWithProps = props => React.Children.map(children, child => React.cloneElement(child, { ...props }))}
    return <Route {...props} render={childrenWithProps} />
}

Usage:

<RouteWrapper
    exact
    path="/">
    <Component myProp={38} />
</RouteWrapper>

Upvotes: 0

Harshal Yeole
Harshal Yeole

Reputation: 4983

This will do the work: Render

    <Route
      path='/dashboard'
      render={(props) => <Dashboard {...props} isAuthed={true} />}
    />

Hope this helps!

Upvotes: 8

Related Questions