question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Fix <Route children>

See original GitHub issue

There was a lot of discussion in #5583 about removing the <Route children> prop and adding a new prop about when to render. The conversation in that issue stalled, so I’d like to resume it here, but with a completely different proposal.

The core issue is that it’s not very clear what the difference is between <Route children> and <Route render>. The API doesn’t really say anything about when to use one over the other.

In contrast to the proposal in #5583 (remove children and add a new prop about when to render) I’d like to propose that we just tweak the way children works and get rid of render (eventually). Here’s why:

Currently, <Route children> always renders, which doesn’t make any sense. Wanna see something crazy?

<Route path="/about" children={() => (
  <About />
)} />

// or even

<Route path="/about">
  <About />
</Route>

You might think these routes only render when the URL path is /about, but nope. They both will render at any URL. 🙃 This is a huge mistake in the v4 API, and I’d be very surprised if anyone is actually using <Route children> like this.

The reason this API exists is because you’re supposed to check the match prop to see if the <Route> matched before rendering anything, e.g.:

<Route path="/about" children={props => (
  props.match ? <About /> : <NotFound />
)} />

So now if the URL is /about you’ll get the <About> page, otherwise <NotFound>. That at least makes a little more sense than the previous examples, and hopefully redeems us a little. But it doesn’t change the fact that the first examples are just crazy.

The vast majority of the time you want to render something only when the route matches the URL, and ignore misses. So we added the <Route render> and <Route component> APIs that will only render something when it matches. These are used much more commonly than <Route children> in all our docs and examples.

The Proposal

It’s quite simple, really: The default behavior of children should be to only render something when the route matches the URL. We don’t need any new API to <Route>, and we definitely don’t want to get rid of the children prop. We just need to fix it.

What about misses?

The majority of the time someone wants to handle a “miss”, they actually want to render a “not found” page. We actually already have great support for this inside a <Switch>:

<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route component={NotFound} />
</Switch>

For the rare use case that someone wants to render a standalone <Route> that does not match the URL, we already provide the matchPath function. If we want a component API, we can provide a lower-level component, call it a <Match>, that will just compute the match and tell you whether or not the path matched:

<Match path="/about">
  {match => match ? <About /> : <NotFound />}
</Match>

Pros:

  • <Route children> is a lot more intuitive
  • Since <Route children> would behave the same as <Route render>, we can eventually remove <Route render> (less API is almost always a good thing)
  • If a <Route> always matches, it will be a lot easier to implement relative <Route>s and <Link>s (see #5127)
  • It should be easier (but still not super easy) to wrap a <Route> now with your own component, since you have one less render prop to worry about

Cons:

  • It is technically a breaking change for what I suspect is a very small percentage of our users
  • ??

The Plan

  • 4.x: Add a <Match> component and encourage everyone who is using children to render something when a <Route> doesn’t match a URL (probably a very small % of users) to use a <Match> instead. Unfortunately, there’s no easy way for us to warn users to stop using children for non-matches.
  • 5.0: Make the switch so <Route> only renders something when it matches. I would expect this to break very few apps, but hey, you never know. Also, keep the render prop around for a while to ease the upgrade.
  • 5.x: Deprecate the render prop since it’s identical to children now and warn people to just use children instead.

Thoughts?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:50
  • Comments:25 (15 by maintainers)

github_iconTop GitHub Comments

19reactions
mjacksoncommented, Oct 1, 2018

Thanks for the feedback, @bradwestfall 😃 The reason I like children, especially in this case, is because it’s more flexible than render because there are 2 different syntaxes for the children prop in JSX.

<Route path="/about" children={() => (
  <About />
)} />

// or:

<Route path="/about">
  <About />
</Route>

vs

<Route path="/about" render={() => (
  <About />
)} />

Plus I’m seeing the community settle more on children than render as far as prop name goes (e.g. the new context API).

3reactions
rgdelatocommented, Oct 1, 2018

As a rebuttal, I’d prefer to see children stay over render (and I don’t necessarily think a Twitter poll is a great way to determine an API). But yeah, the proposed changes look great to me, including the addition of a <Match> component that just gives its children the result from matchPath.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to fix the children routing? - javascript - Stack Overflow
When i click on the buttom with the [routerLink] the URL is changing ,but! the page stay in the same componnent - The...
Read more >
Fix <Route children> · Issue #6362 · remix-run/react-router
It's quite simple, really: The default behavior of children should be to only render something when the route matches the URL. We don't...
Read more >
Angular Router: Child Routes, Auxiliary Routes, Master Detail
Learn how to use the Angular Router, avoid common pitfalls, learn Child Routes, Auxiliary Routes, setup a Master Detail Routing Scenario.
Read more >
What is Child Routes in Angular - YouTube
In this lecture, we will have a look at how to add a child or nested routes to an Angular route. Child Routes...
Read more >
Angular 14 Child Nested Routing. Divide Routes to ... - YouTube
In this video we will see about the Angular V14 child Nested Routing and divide the routes into s separate file. Preserve and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found