user9667412
user9667412

Reputation:

Why child route won't render without the parent route rendering?

I am trying to navigate to /movie/:title on which I am rendering a new page. But it only renders if my movie page i.e /movie renders, but I don't want my movie page to be mounted on navigating to /movie/:title. I only want it as part of the path. Making the /movie path exact doesn't work as /movie/:title wouldn't render with /movie as exact.

App.js

class App extends React.Component {
 render() {
  return (
   <div>
      <Header />
      <Route path='/movies' component={Movies} />
      <Route path='/tvshows' component={TvShow} />      
   </div>
)}

Movie.js

return (
   <div className="movies">
        <Route path={`${match.path}`} render={(props) => <CollectionGrid movies/>} />
        <Route path={`${match.path}`} render={(props) => <CollectionOverview movies/>} />
        <Route path={`${match.path}/:title`} component={ItemPage} />
   </div>
);

Upvotes: 1

Views: 1194

Answers (2)

Mohammed Al-Reai
Mohammed Al-Reai

Reputation: 2786

you are not able to access to match direct in this app the match is found in this .props.match you cand used it in

const App({match})

then when you need to used it should

<Route path={`${match.path}`} render={(props) => <CollectionGrid movies/>} />

look to this example and explain

Upvotes: 0

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

A couple of notes. Conventionally, you should keep all your routes in a single router, thus making it easier to navigate and identify your application.

Organize your Router like this:

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "./Home";
import Movies from "./Movies";
import ItemPage from "./ItemPage";

const App = () => {
  return (
    <BrowserRouter>
      <div>
        <Switch>
          <Route path="/" component={Home} exact />
          <Route path="/movies/:title" component={ItemPage} />
          <Route path="/movies" component={Movies} />
        </Switch>
      </div>
    </BrowserRouter>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Additionally, to resolve your solution, you would need the Switch component, which is available in react-router-dom. The Switch component, will look through a list of Routes and will only render the FIRST Route who's path string is included within the URL string.

In the list above we have 3 Routes. If your URL is "/movies/blah", it will only render the ItemPage component, because that Route's path was matched first within the list.

We moved the "/movies/:title" Route before the regular "/movies" for this very reason. If the "/movies" Route appeared first in the list and if your URL was "/movies/blah", it would still satisfy the "/movies" Route. That means Switch would only render Movies component, which is not what you want.

See working sandbox: https://codesandbox.io/s/hopeful-bogdan-lzl76

Upvotes: 1

Related Questions