skip to Main Content

I get this warning when I wrapped my component in <Routes>.

Warning: [Categories] is not a <Route> component. All component
children of <Routes> must be a <Route> or <React.Fragment>

App.js

const App = () => {
   return (
        <div className="app__container">
            <Header />
            <Nav />
            <BrowserRouter>
                <Routes>
                    {/* This two component get warning */}
                    <Categories />
                    <Details />      
                </Routes>
            </BrowserRouter>
        </div>
    )
}

Categories.js

const Categories = () => {
  return (
    <>    
        <Route path="/" element={<Navigate replace to="/movie" />} />    

        <Route path="/movie" element={<Movies /> } />
        <Route path="/tv" element={<Tv />}/>
        <Route path="/person" element={<People />} />
        <Route path="/search" element={<Search />} />
    </>
  )
}

Details.js

const Details = () => {
  return (
    <>
        <Route path="/movie/:tmdbID" element={<MovieDetail />}/>
        <Route path="/tv/:tmdbID" element={<TvDetail />}/>
        <Route path="/person/:tmdbID" element={<PersonDetail/>}/>
    </>
  )
}

As you can see, it seems like <Routes> won’t take just Categories and Details as a children.

I’m doing it because I want the Route to be placed in different folder/file. Which in Categories.js and Details.js

So, how can I manage this?

2

Answers


  1. The error is accurate. Categories and Details are not <Route> values, the are their own component values. The fact that they have <Route> elements within their JSX does not make them <Route> elements.

    If this is a new project, you might consider going with React-Router newer createBrowserRouter() construct where you define routes as data (an array of JS objects) rather than as JSX elements. Then you could define Categories and Details as data and reference that data anywhere in your code.

    Use of createBrowserRouter() is the recommended way forward for people using React-Router.

    Login or Signup to reply.
  2. The Routes component can only have Route or React.Fragment as valid children. Neither Categories or Details can be rendered directly by Routes like this.

    Render all the routes together as in the following:

    const App = () => {
      return (
        <div className="app__container">
          <BrowserRouter>
            <Header />
            <Nav />
            <Routes>
              <Route path="/" element={<Navigate replace to="/movie" />} />
              <Route path="/search" element={<Search />} />
    
              <Route path="/movie">
                <Route index element={<Movies /> } />
                <Route path=":tmdbID" element={<MovieDetail />} />
              </Route>
    
              <Route path="/tv">
                <Route index element={<Tv />} />
                <Route path=":tmdbID" element={<TvDetail />} />
              </Route>
    
              <Route path="/person">
                <Route index element={<People />} />
                <Route path=":tmdbID" element={<PersonDetail/>} />
              </Route>
            </Routes>
          </BrowserRouter>
        </div>
      );
    };
    

    This organization uses nested routes.

    Or if you are trying to code-split you can split the routes logically by routes/sub-routes where components render descendent routes. In order for descendent routes to work the parent route path appends a wildcard matcher, or splat, "*" to its path and the routed component renders another Routes and set of Route components.

    const MovieRoutes = () => (
      <Routes>
        <Route path="/" element={<Movies /> } />
        <Route path="/:tmdbID" element={<MovieDetail />} />
      </Route>
    );
    
    const TvRoutes = () => (
      <Routes>
        <Route path="/" element={<Tv />} />
        <Route path="/:tmdbID" element={<TvDetail />} />
      </Route>
    );
    
    const PersonRoutes = () => (
      <Routes>
        <Route path="/" element={<People />} />
        <Route path="/:tmdbID" element={<PersonDetail/>} />
      </Route>
    );
    
    const App = () => {
      return (
        <div className="app__container">
          <BrowserRouter>
            <Header />
            <Nav />
            <Routes>
              <Route path="/" element={<Navigate replace to="/movie" />} />
              <Route path="/search" element={<Search />} />
    
              <Route path="/movie/*" element={<MovieRoutes />} />
              <Route path="/tv/*" element={<TvRoutes />} />
              <Route path="/person/*" element={<PersonRoutes />} />
            </Routes>
          </BrowserRouter>
        </div>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search