What's the better way to configure routes in App.js in React with react-router-dom

Viewed 140

In App.js of React, we can either:

<div className="App">
  <Router>
    <Switch>
      <Route
        path="/basics"
        >
        <BasicsPage></BasicsPage>
      </Route>
      // other routes
    </Switch>
  </Router>
</div>

OR

<div className="App">
  <Router>
    <Switch>
      <Route
        path="/basics"
        component={BasicsPage}
        >
      </Route>
      // other routes
    </Switch>
  </Router>
</div>

Just wondering which is the better way to write it and if there' any difference between the two? Thanks!

3 Answers

The second solution is the best mainly because it provide matches props to the component.

Here is a codesandbox exemple. (check the index.js file than contain routes)

But each solution is usefull.

If you want pass props to the BasicPage the first way is better to add all of props you want.

But if you have the choice, use the second solution which is more maintainable and clean for the future of your app.

If you need to provide your custom props and props given by react-router you can use the third solution is :

<Route exact path="/" render={(props) => <App matches={props} myProps={1} />} />

It depends on if you want/need the route props (history, location, and match) passed on to the component.

<div className="App">
  <Router>
    <Switch>
      <Route
        path="/basics"
        component={BasicsPage} // <-- route props passed
      />
      <Route
        path="/basics"
      >
        <BasicsPage /> // <-- route props not passed
      </Route>
      // other routes
    </Switch>
  </Router>
</div>

However, if you needed to pass additional props on to a component, then the second method allows for that.

<div className="App">
  <Router>
    <Switch>
      <Route
        path="/basics"
      >
        <BasicsPage myCustomProp={someValue} /> // <-- pass custom prop
      </Route>
      // other routes
    </Switch>
  </Router>
</div>

And if you needed the route props and to pass additional props, then use the render prop.

<div className="App">
  <Router>
    <Switch>
      <Route
        path="/basics"
        render={routeProps => (
          <BasicsPage
            {...routeProps}          // <-- pass route props
            myCustomProp={someValue} // <-- and pass custom prop
          />
        )}
      />
      // other routes
    </Switch>
  </Router>
</div>

Route render methods:

The recommended method of rendering something with a <Route> is to use children elements, as shown below. There are, however, a few other methods (see this) you can use to render something with a <Route>. These are provided mostly for supporting apps that were built with earlier versions of the router before hooks were introduced.

Example:

<Router>
  <Switch>
    <Route path="/basics">
      <BasicsPage />
    </Route>
    <Route path="/foo">
      <Foo>Some children here</Foo>
    </Route>
  </Switch>
</Router>

Use the above method for declaring all the routes and use hooks (useHistory, useLocation, useParams etc.) to access the router's internal state. This style will also make it easy to switch to React Router v6. See this as pointed out by @jonrsharpe in the comment.

Related