React Router doesn't match path - reactjs

This is my routing configuration, when i access the index route which is "/"
it works perfectly fine, but when i access the /posts and /response route, it cant resolve it.
See that is my index route. and this happens when i go to posts or response route

Ok, first of all, it seems like you're using an unnecessary Router component, you can check here why: https://reacttraining.com/react-router/web/api/Router
Also, you can wrap your routes inside a Switch component, but you will have to change the order of them since a Switch only renders the first route that matches the path given. You can read more about that here https://reacttraining.com/react-router/web/api/Switch. So your routes definition will become something like this:
<Switch>
<Route path="/r1" render={() => <h1>route 1</h1>} />
<Route path="/r2" render={() => <h1>route 2</h1>} />
<Route exact path="/" component={SomeComponent} />
</Switch>

try wrapping your all 3 Route inside a Switch statement

Related

Redirecting to subpage with id

I've had two routes:
<Route path="/client/:id/members" component={Members} />
<Route path="/client/:id/members/:mid" component={MemberProfile} />
why when I'm trigger:
window.location.href = `/client/${id}/members/${mid}`;
then my url is changed to correct form like in the route path but not redirect me to MemberProfile component?
Thanks for any help!
as
<Route path="/client/:id/members" component={Members} />
declared before
<Route path="/client/:id/members/:mid" component={MemberProfile} />
and
/client/${id}/members/${mid}
fit
"/client/:id/members"
Members component will still be rendered.
Consider one of the following:
decleare MemberProfile before Members
change MembersProfile route to /client/:id/member/:mid for example
use exact Route property
Given:
<Route path="/client/:id/members" component={Members} />
<Route path="/client/:id/members/:mid" component={MemberProfile} />
It seems like you are rendering these routes into a Switch component. Remember that the Switch component renders the first child <Route> or <Redirect> that matches the location. This means that route path order and specificity matters.
Order your routes by decreasing specificity. "/client/:id/members/:mid" is more specific than "/client/:id/members" and should render higher in the Switch.
<Switch>
...
<Route path="/client/:id/members/:mid" component={MemberProfile} />
<Route path="/client/:id/members" component={Members} />
...
</Switch>
Additional note
You may want to avoid using window.location.href to redirect as this reloads the entire page, and thus, your app. Use a Redirect component to render a declarative navigation, or use history.replace(`/client/${id}/members/${mid}`); to issue an imperative redirect.

why two routes calling same page in react js that has different path link

<Route path={${process.env.PUBLIC_URL}/book-repair/:name/:name} component={Modals}/>
<Route path={${process.env.PUBLIC_URL}/book-repair/:name} component={Companies}/>
when call second route this is calling very well. but when am call first route first route and second route both are calling. please solve my issue.
Use Switch to render the Routes Exclusively and use exact to strictly match the pattern
import { Route, Switch } from "react-router";
let routes = (
<Switch>
<Route path={${process.env.PUBLIC_URL}/book-repair/:name/:name} component={Modals} exact />
<Route path={${process.env.PUBLIC_URL}/book-repair/:name} component={Companies} exact />
</Switch>
);
Refer: https://reactrouter.com/web/api/Switch
<Switch><Route path={${process.env.PUBLIC_URL}/book-repair/:name/:name} exact component={Modals}/>
<Route path={${process.env.PUBLIC_URL}/book-repair/:name} exact component={Companies}/> </Switch>
You should add exact and Switch to your routes.
If you are rendering the routes into a Router they both can be matched and rendered. The Router inclusivley matches and renders routes. Use the exact prop to exactly match one or the other. The issue is that ${process.env.PUBLIC_URL}/book-repair/:name is a prefix for ${process.env.PUBLIC_URL}/book-repair/:name/:name, and so will also be matched.
<Route
exact
path={`${process.env.PUBLIC_URL}/book-repair/:name/:name`}
component={Modals}
/>
<Route
exact
path={`${process.env.PUBLIC_URL}/book-repair/:name`}
component={Companies}
/>
The alternative is to render the routes into a Switch to exclusively match and render routes. Here path order and specificity matter. Order your routes from most specific to least specific. You don't need to specify the exact prop since the Switch only matches and renders the first matching Route.
<Switch>
...
<Route
path={`${process.env.PUBLIC_URL}/book-repair/:name/:name`}
component={Modals}
/>
<Route
path={`${process.env.PUBLIC_URL}/book-repair/:name`}
component={Companies}
/>
...
</Switch>

React router: Redirecting with url param?

In my render function I have
<Route path="/classes/:course" render={(match) => (
<Redirect to={`/classes/${match.params.course}/home`} />
)}>
<Route path="/home" component={Home} />
</Route>
For example if the param for "course" was "BIO1001", I want to redirect the page to "/classes/BIO1001/home" when I go to the page "/classes/BIO1001/". Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"
Also would the nested route with path="/home" go to "/classes/BIO1001/home"? I was unsure on how I can set a route where the path starts from the previous url (in this case starting from "/classes/:course/"
The first problem is right here:
render={(match) => ( ...
The render function gets a props object which contains a match property. Instead of destructuring the match property, what you are actually doing is assigning the whole props object to a variable match. So when you go to access match.params it won't be found.
You need curly braces around match in order to destructure it.
render={({match}) => ( ...
The second problem is the nesting of the two Route components. I get a warning:
Warning: You should not use <Route render> and <Route children> in the same route; <Route render> will be ignored
So based on that warning you can see that your Redirect is being entirely ignored since it comes from render. The child Route is seen as the render function for the classes Route.
I'm assuming you have various subpages of a course? And we want to force the URL to include "/home" if none is set? (Personally I would do the opposite and redirect "/home" to the course root URL).
Previously I tried simply putting a Redirect tag with "from" and "to" but ran into the problem of the url actually going to "/classes/:course/home" instead of "/classes/BIO1001/home"
Per the docs, you can use params in your Redirect, but only if it is inside a Switch.
Here's a sample code to do that:
const CoursePage = () => {
// you can access arguments from the props or through hooks
const { course, tab } = useParams();
// not sure how you want to handle the different tabs
return <div>Viewing Course {course}</div>;
};
const App = () => (
<BrowserRouter>
<Switch>
<Route path="/classes/:course/:tab"><CoursePage/></Route>
<Redirect from="/classes/:course" to="/classes/:course/home"/>
</Switch>
</BrowserRouter>
);
export default App;
Your nested routing is true i think. But you are rendering your Home component without any dynamic props. Try it like below:
<Route path="/classes/:course" render={(match) => (
<Redirect to={`/classes/${match.params.course}/home`} />
)}>
<Route path="/home" >
<Home someProps={someValue} />
</Route>
</Route>
Note: The Redirect element can be used without a containing Route element by providing a from property. In this case, you can just use the URL parameter tokens in both from and to, and they'll be carried over for you. For example, if you're using a Switch block...
<Switch>
{/* various app routes... */}
{/* redirect action */}
<Redirect from="/classes/:course" to="/classes/:course/home" />
<Switch>

React Router: Wrapping some Routes with a component and not directly inside Switch

I'm trying to do something like this
<Switch>
<SomeNavBar>
<Route path="page1">Page 1</Route>
<Route path="page2">Page 2</Route>
<Route path="page3">Page 3</Route>
</SomeNavBar>
<OtherNavBar>
<Route path="admin">Admin Page</Route>
</OtherNavBar>
</Switch>
Where I have wrapper component for a routes that are not the admin page.
However the admin route does not render Admin Page it just renders a blank page. The other routes work fine.
Is there a way to achieve this behavior?
There's a couple of issues with your example not related to the question which you should rectify before anything else.
The first is that the direct children of a Switch must always be a Route or Redirect - it doesn't know what to do with any other element and will just render the first thing it sees (in your case, the SomeNavBar component). The second is that path declarations must be prepended with a slash for the router to build them correctly, so /page1 and /admin for example.
With that out the way, here is a somewhat contrived example of how to get the behaviour you are after. For the pages, we are checking from a list of possible fragments before rendering SomeNavBar and the correct route. Notice also the exact parameter - this is so we don't also match paths that only begin with the specificed fragment, like /page1foo:
<Switch>
<Route exact path={['/page1', '/page2', '/page3']}>
<SomeNavBar>
<Route path="/page1">Page 1</Route>
<Route path="/page2">Page 2</Route>
<Route path="/page3">Page 3</Route>
</SomeNavBar>
</Route>
<Route path="/admin">
<OtherNavBar>
Admin Page
</OtherNavBar>
</Route>
</Switch>

React router dom params issue

I tried to Routing the params ":id" in react with a sub Route ":id/history" and the route link not render the component on clicking
<Switch>
<Route path="/patients/:id" exact component={GeneralData} />
<Route path="/patients/:id/history" component={History} />
</Switch>
The Switch component renders the first route that matches the URL you entered
Because you are using a wildcard for your GeneralData Route like so
<Route path="/patients/:id" component={GeneralData}/>
No matter what you enter after /patients, it gets captured in that wildcard definition of that Route because it accepts literally anything. So even if you navigate to /patients/4834834/history it still satisfies the GeneralData route which was found first in the list of routes.
To fix this, simply move your History Route above your GeneralData Route. This makes it so the GeneralData route will not get rendered for anything that just satisfies /patients/:id. Switch will look to see if your URL matches History first.
<Switch>
<Route path="/patients/:id/history" component={History} />
<Route path="/patients/:id" component={GeneralData} />
</Switch>
I think you're omitting exact param.

Resources