Tom Hanson
Tom Hanson

Reputation: 663

React Router Switch not rendering specific component

I have a React app that is currently using [email protected] and I'm struggling with rendering a specific component when the URL changes.

When I try to visit /locations/new it returns with a PropTypes error from the CityList component. I have tried adding in exact to the Route component within LocationsWrapper and then Main config too, however, this then influences other routes - such as /locations to become null.

// BrowserRouter

import React from "react";
import { render } from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";

import store from "./store";
import Navbar from "./components/Core/Navbar";
import Routes from "./config/routes";

render(
  <Provider store={store}>
    <BrowserRouter>
      <div style={{ backgroundColor: "#FCFCFC" }}>
        <Navbar />
        <Routes />
      </div>
    </BrowserRouter>
  </Provider>,
  document.getElementById("root")
);

// Router config - ( Routes )

import React from "react";
import { Route, Switch } from "react-router-dom";

import Home from "../components/Home";
import Locations from "../components/Locations";
import CityList from "../components/CityList";
import CreateLocation from "../components/CreateLocation";
import Locale from "../components/Locale/index";
import Profile from "../components/Profile";
import NoMatch from "../components/Core/NoMatch";

import requireAuth from "../components/Core/HOC/Auth";

const LocationsWrapper = () => (
  <div>
    <Route exact path="/locations" component={Locations} />
    <Route path="/locations/new" component={CreateLocation} />
    <Route path="/locations/:id" component={CityList} />
  </div>
);

const Main = () => (
  <main>
    <Switch>
      <Route exact path="/" component={requireAuth(Home)} />
      <Route path="/locations" component={LocationsWrapper} />
      <Route path="/locale/:id" component={Locale} />
      <Route path="/profile" component={requireAuth(Profile, true)} />
      <Route component={NoMatch} />
    </Switch>
  </main>
);

export default Main;

Am I best avoiding <Switch> entirely and implementing a new method for routes that are undefined - such as 404s?

Upvotes: 0

Views: 4203

Answers (2)

birendra
birendra

Reputation: 144

Yes, this will definitely return first

<Route path="/locations/:id" component={CityList} />

In react-router 4 there is no concept of index route, it will check each and every routes so in your defining routes are same

<Route path="/locations/new" component={CreateLocation} />
<Route path="/locations/:id" component={CityList} />

both path are same '/location/new' and '/location/:id' so /new and /:id are same params.

so at last 'CityList' will return

You can define like this

<Route path="/locations/create/new" component={CreateLocation} />
<Route path="/locations/list/:id" component={CityList} />

Upvotes: 0

radlaz
radlaz

Reputation: 318

Pretty sure your route is not working cause you are also matching params with /locations/new with /locations/:id so then 'new' becomes Id param.

Try changing this

   <Route path="/locations/new" component={CreateLocation} />

To something like this

   <Route path="/locs/new" component={CreateLocation} />

Just a suggestion hope this may help

Upvotes: 0

Related Questions