Hello,
I use React-route@v4, I have inside my Router
:
<Layout searchBar>
<Route path="/" render={props => <LandingPage {...props} />} />
</Layout>
My layout contains a components which has a component which has a searchBar. I want the content of the searchBar to change the content of a component of LandinPage
.
I don't know the best way but I end up with a solution which makes LandingPage
having the searchRequest
. Now the variable climbed up to the parent component I need to make the variable going down to DrugsList
. So my idea was to give to the children
component of the layout the prop searchRequest
by replacing {children}
with :
{React.cloneElement(children, {
searchRequest,
})}
However <Route path="/" render={props => <LandingPage {...props} />} />
keeps the props for him and doesn't want to give'em to LandingPage
so how should I do ?
Actually I'm not only open to understand how making Route
passing props to its component but also by finding another way (if you think it's better) to make my components communicating.
You would need to wrap Route in your own component that passes through its props to the render function directly. Basically, how NavLink works: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/NavLink.js
Well, it worked :
const LandingRoute = ({ searchRequest }) => (
<Route
path="/" children={() =>
<LandingPage searchRequest={searchRequest} />}
/>
);
Meteor.startup(() => {
render(
<Router history={history}>
<Switch>
<Route path="/">
<Layout searchBar>
<LandingRoute />
</Layout>
</Route>
</Switch>
</Router>, document.getElementById('app'));
});
Why Route doesn't pass props by default though ?
I ended up creating a PorousRoute
, it's a reusable component which always pass props to its children :
import React from 'react';
import Route from 'react-router';
export default function ({ children, ...props }) {
return (
<Route path={props.path}>{React.cloneElement(children, props)}</Route>
);
}
I just ran into a similar issue while migrating to v4 and pulled my hair out for quite a while. The docs clearly state that Route children get props too, so cloneElement
should be the default behaviour. Can we re-open this?
Route render methods
There are 3 ways to render something with a
:
Each is useful in different circumstances. You should use only one of these props on a given
. See their explanations below to understand why you have 3 options. Most of the time you’ll use component. Route props
All three render methods will be passed the same three route props
- match
- location
- history
hi all! just wondering if there any updates on this issue? is this the expected behavior?
I am also having trouble passing props into the render prop of
I could recommend to declare props in react-redux connect
mapStateToProps
2017-07-26 8:58 GMT+08:00 Kyle Miller notifications@github.com:
I am also having trouble passing props into the render prop of . My
confusion comes in where I'm supposed to declare the array of props to be
inserted into the router line component.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/ReactTraining/react-router/issues/4942#issuecomment-317915656,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACJseYPjRjFDk-7Xdtn7x6LVlJoW8qp-ks5sRo8rgaJpZM4M4L1Z
.
Is there no way to do this?
render(){
if (this.props.data.loading) {
return <LoadingScreen />
}
return (
<div className='public-layout'>
<Switch>
<Route exact path='/' component={ SignupPage } {...this.props} />
<Route exact path='/login' component={ LoginPage } {...this.props} />
</Switch>
</div>
);
}
@acomito that's not really the same thing. You can achieve that, for example, by using render={() => <SignupPage {...this.props} />}
instead of component={...}
. But this issue is about the router-specific props (location etc.) not getting injected automatically.
@skosch Thanks for the quick response. That's the answer I needed to track down. Sorry to clog up the wrong thread!
(... or even just <Route ...><SignupPage {...this.props /></Route>
would work for you too – but again, the problem is that SignupPage wouldn't get access to props.location
etc.)
i see... so to get props.location we need to do React.clone for each route?
Well we shouldn't have to, thus this issue ... :wink:
True. Yeah one of the pages (SignupPage) has on it.. so I can get my this.props.data there with your fix, but am getting this error still:
Failed context type: The context router.push
is marked as required in Link
, but its value is undefined
.
I found a solution to this issue
<Router path="/somePath" render={() => <SomeComponent someProp={prop} />} />
The docs make things overly complicated. Just think of it as writing a component like you would in any other location.
I'm just using the implicit return, anything more complicated doesn't seem to work
From here you still have access to this.props.someProp inside the child component
@KyleWMiller, this is the most simple way to pass props, but bad thing is that when i use it i can't see "match.params" property.
So, for me it works great with simple routes, but not with routes like that
<Route exact path="/conceptions/:id" name="Conception" render={() => <Conception wtf={"wtf"} {...this.props} />}/>
@Charlie91
<Route exact path="/conceptions/:id" render={({ match }) => <Conception match={match} {...this.props} />}/>
@timdorr yeah, it seems i made a mistake i have found it already.
thank you for fixing me!
what a dirt! would be something like this :
BrowserRouter>
I also tried this.
// @flow
import React, { Component } from 'react';
import { observer } from 'mobx-react';
/** Modules **/
import MainStore from './MainStore';
/** Stylesheets **/
import './App.css';
@observer
class App extends Component {
mainStore: MainStore;
constructor() {
super();
this.mainStore = new MainStore();
}
render() {
const { children } = this.props;
return (
<div className="App">
{React.cloneElement(children, { api: this.mainStore.api })}
</div>
);
}
}
export default App;
This doesn't work in react-router v4, but DOES work in react-router v3. -_-
I like dom better htough, oh well.... I am adding a comment because if this get's resolved I'll go back to v4
edit -
https://stackoverflow.com/questions/43469071/react-react-router-dom-pass-props-to-component
great explanation here.
Most helpful comment
I just ran into a similar issue while migrating to v4 and pulled my hair out for quite a while. The docs clearly state that Route children get props too, so
cloneElement
should be the default behaviour. Can we re-open this?