react-router v4: how to avoid rendering parent routes when child routes miss
<p>I'm trying to render most of my routes as children of an <code>AppShell</code> component, which contains a navbar.  But I want to render my 404 route as a standalone component not wrapped in <code>AppShell</code>.</p>

<h3>It was easy with v2:</h3>

<pre><code>&lt;Router&gt;
  &lt;Route component={AppShell}&gt;
    &lt;Route path="/about" component={About} /&gt;
    &lt;Route path="/" component={Home} /&gt;
  &lt;/Route&gt;
  &lt;Route path="*" component={NotFound} /&gt;
&lt;/Router&gt;
</code></pre>

<p>Everything works as desired:</p>

<ul>
<li><code>/</code> renders <code>&lt;AppShell&gt;&lt;Home /&gt;&lt;/AppShell&gt;</code></li>
<li><code>/about</code> renders <code>&lt;AppShell&gt;&lt;About /&gt;&lt;/AppShell&gt;</code></li>
<li><code>/blah</code> renders <code>&lt;NotFound /&gt;</code></li>
</ul>

<h3>But I can't figure out how to do it with v4:</h3>

<p>Right now I'm doing this, but the problem is it renders <code>AppShell</code> (with no children, but still a navbar):</p>

<pre><code>const Routes = () =&gt; (
  &lt;div&gt;
    &lt;AppShell&gt;
      &lt;Match exactly pattern="/" component={Home} /&gt;
      &lt;Match pattern="/about" component={About} /&gt;
    &lt;/AppShell&gt;
    &lt;Miss component={NotFound} /&gt;
  &lt;/div&gt;
)
</code></pre>

<p>With this:</p>

<ul>
<li><code>/</code> renders <code>&lt;div&gt;&lt;AppShell&gt;&lt;Home /&gt;&lt;/AppShell&gt;&lt;/div&gt;</code> (good)</li>
<li><code>/about</code> renders <code>&lt;div&gt;&lt;AppShell&gt;&lt;About /&gt;&lt;/AppShell&gt;&lt;/div&gt;</code> (good)</li>
<li><code>/blah</code> renders <code>&lt;div&gt;&lt;AppShell /&gt;&lt;NotFound /&gt;&lt;/div&gt;</code> <strong>(problem -- I want to get rid of the <code>&lt;AppShell /&gt;</code>)</strong></li>
</ul>

<h3>Using an array <code>pattern</code> works if there's no root route:</h3>

<pre><code>const InAppShell = (): React.Element&lt;any&gt; =&gt; (
  &lt;AppShell&gt;
    &lt;Match pattern="/about" component={About} /&gt;
    &lt;Match pattern="/contact" component={Contact} /&gt;
  &lt;/AppShell&gt;
)

const App = (): React.Element&lt;any&gt; =&gt; (
  &lt;div&gt;
    &lt;Match pattern={['/contact', '/about']} component={InAppShell} /&gt;
    &lt;Miss component={NotFound} /&gt;
  &lt;/div&gt;
)
</code></pre>

<h3>And using an array <code>pattern</code> with <code>exactly</code> works with the root route:</h3>

<p>But then I have to put <em>all possible child routes</em> in the <code>pattern</code> array...</p>

<pre><code>const InAppShell = (): React.Element&lt;any&gt; =&gt; (
  &lt;AppShell&gt;
    &lt;Match exactly pattern="/" component={Home} /&gt;
    &lt;Match pattern="/about" component={About} /&gt;
  &lt;/AppShell&gt;
)

const App = (): React.Element&lt;any&gt; =&gt; (
  &lt;div&gt;
    &lt;Match exactly pattern={["/", "/about"]} component={InAppShell} /&gt;
    &lt;Miss component={NotFound} /&gt;
  &lt;/div&gt;
)
</code></pre>

<p>But that would be pretty unwieldly in a large app with a bunch of routes.</p>

<h3>I could make a separate <code>Match</code> for <code>/</code>:</h3>

<pre><code>const InAppShell = (): React.Element&lt;any&gt; =&gt; (
  &lt;AppShell&gt;
    &lt;Match exactly pattern="/" component={Home} /&gt;
    &lt;Match pattern="/about" component={About} /&gt;
    &lt;Match pattern="/contact" component={Contact} /&gt;
  &lt;/AppShell&gt;
)

const App = (): React.Element&lt;any&gt; =&gt; (
  &lt;div&gt;
    &lt;Match exactly pattern="/" component={InAppShell} /&gt;
    &lt;Match pattern={["/about", "/contact"]} component={InAppShell} /&gt;
    &lt;Miss component={NotFound} /&gt;
  &lt;/div&gt;
)
</code></pre>

<p>But this would remount <code>&lt;AppShell&gt;</code> every time I transition to and from the home route.</p>

<p>There doesn't seem to be an ideal solution here; I think this is a fundamental API design challenge v4 will need to solve.</p>

<p>If only I could do something like <code>&lt;Match exactlyPattern="/" pattern={["/about", "/contact"]} component={InAppShell} /&gt;</code>...</p>