react-router: v6 beta, cant pass props through Outlet.
My current project’s previous team had used a lot of cloneElement to pass props to nested routes.
{Children.map(children, (child) =>
cloneElement(child, {
somefunc: this.somefunc,
})
)}
So I got a tons of code to refactor now, and I do not see a way to migrate this code to v6. Do you consider way to allow pass props like <Outlet myProp=1/>, to pass it into underlying route’s component?
I’ll give you an example to be sure
//index.js
<Route path='/' component={<App />} />
<Route path /1' component={<1 />} />
<Route path /2' component={<2 />} />
</Route>
//App.js
render() {
return <Outlet myprop='1' />
}
//1/2.js
this.prop.myprop === 1 // true
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 12
- Comments: 22 (13 by maintainers)
No, because you can pass them via URL parameters.
We definitely have plans to allow passing stuff through outlet. Sorry @timdorr, I should’ve let you know before you closed this.
Right now we’re thinking this will look something like:
In case anyone is looking for a nice solution, do this with context:
Now you’d use
<Outlet data={} />from this code instead of the one from React Router (this one just wraps theirs). Then in the nested page just calluseOutletContext()FWIW, Michael and Ryan are probably going to make something (maybe similar to this) available in RR later (based on some chatter I’m seeing)
@timdorr @MeiKatz Don’t you find this a bit ugly? If I have a series of child routes for a dashboard that all have the same data requirements, wouldn’t it rather convenient to just pass this in once through the
<Outlet />as opposed to passing it through the component in theelementprop?To take another example, consider following routes definition:
If you look real quick at all
courses/*routes, you’ll notice they’re composed by a parent<Courses />element where my<Outlet />statement is. Since all routes under that maincourses/*route need to have access to 1. the data of the specific course in question, 2. all other courses available on the website, and 3. the current user’s progress on all various courses, it would be rather inconvenient to pass these props on all theelement’s that fall under that tree. Wouldn’t it just be better to pass them as props on the<Outlet />itself? If we don’t have the ability to do that, I need to make all 3 of these API calls at the top of my routes definition file, even though the data is only relevant for roughly half the routes on my entire site.Is there some particular reason you wouldn’t want data to be able to be passed as a prop on an
<Outlet />component? Does this greatly increase the complexity of the API you’re offering in v6?Adding a reference to this other issue with the same question: https://github.com/ReactTraining/react-router/issues/7590
You can pass them to the element in
<Route />This is now possible with
<Outlet context>in 6.1.0Meaning there is no way to pass props from Parent to Child in a declarative routing system? If we can’t pass props from parent to child in such a way, the declarative routing is just for Layouts? I’m trying to have the routing of my whole app is a declarative way. Is it possible?
Stumbled across this myself today. So instead of using the Outlet, one is supposed to pass everything through the
<Route/>'s renderedelement? Curious if there is anything to read up about the thought process behind it and whether it is in discussion to change it.Use Case:
Users:
User:
I think the concept of Descendant Routes would help me here, however, I would love to declare all routes at the top and use the Outlet as a tunnel instead.
@SKOLZ Take a look at
useMatches. It lets you access route data from all active routes.https://reactrouter.com/en/main/hooks/use-matches
@timdorr thanks for update but
<Outlet context />still not working getting undefined, I’ve updated to v6.1.1. Added details in #8492@rwieruch https://reactrouter.com/docs/en/v6/api#useoutletcontext
In this case: why don’t you use a custom context?
Can we reconsider this ? There is certain props I do not want to pass via URL parameters