React-router nested rotues - reactjs

This is how my Routing looks:
<Router history={createBrowserHistory()}>
<Route path="/" component={App}>
<IndexRoute component={EventAppContainer}/>
<Route path="fights" component={FightApp}/>
<Route path="fighters" component={FightersAppContainer}>
<Route path="/fighter/:id" component={FighterDetails} />
</Route>
</Route>
</Router>
In FightersAppContainer I fetch some data, if I render everything from there my nested route works perfectly. But If I want to have more children components, for example FightersAppContainer=>FightersApp=>FighterItem then I cannot reach my nested route. I do not get any error it just doesn't show up. How can I fix this?
To be more clear if I use <Link to={"/fighter/"+fighter.id}>{fighter.last_name}</Link> inside FightersAppContainer I achieve what I want. But if I try that inside for example FighterItem component (that is a child of FightersAppContainer component) then I don't get the desired result, as a matter of fact I don't get anything including errors...

The problem is that this:
<Route path="/fighter/:id" component={FighterDetails} />
being a child of the fighters path, would be expecting the route to be /fighters/fighter/:id, so your Link element would have to look like this if you're not on the fighters element itself:
<Link to={"/fighters/fighter/"+fighter.id}>{fighter.last_name}</Link>

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.

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>

In ReactJs using routes, how do I pass a hidden parameter without being in the URL?

Currently in my code I need to pass a value from one component to the other through a button using router link ..
I am able to do this, but this value is appearing in the URL, appearing as if I had sent a GET.
I want to be able to pass this value on to the other component in a hidden way.
See the important parts of my code:
In TotalCartComponent:
<Link to={"/orderproduct/" + total}>ADVANCE</Link>
In OrderProduct:
<h1>HELLO!!</h1>
<h4>Total is: {this.props.match.params.total}</h4>
In AppShell:
<main>
<Switch>
<Route exact path="/" component={Main}/>
<Route path="/mycart" component={MyCart}/>
<Route path="/orderproduct/:total" component={OrderProduct}/>
<Route path="/view1" component={View1}/>
</Switch>
</main>

React Router v4 Route difference

I am creating routing for my react app, could someone explain me difference between these two approaches.
From user point of view they work the same, what is the difference in performance, best practice?
First one is multiple Routes rendering different component for the same path:
<Route path='/:shop/booking' component={Services}/>
<Route path='/:shop/booking' component={Calendar}/>
Second is single path rendering components as props.children(?) :
<Route path='/:shop/booking'>
<Aux>
<Services/>
<Calendar/>
</Aux>
</Route>
<Route path='/'>
<Component>
</Route>
Is equivalent to :
<Route path='/' children={Component}/>
According to this : https://reacttraining.com/react-router/core/api/Route/children-func :
Sometimes you need to render whether the path matches the location or
not. In these cases, you can use the function children prop. It works
exactly like render except that it gets called whether there is a
match or not.The children render prop receives all the same route
props as the component and render methods, except when a route fails
to match the URL, then match is null. This allows you to dynamically
adjust your UI based on whether or not the route matches.
So by giving children prop instead of component to your route, you force it to render even if the current URL does not match. And I might be mistaking but it seems that adding a component prop to a route override its children prop.
Thus you cannot expect the same behavior for this two pieces of code :
<Route path='/:shop/booking' component={Services}/>
<Route path='/:shop/booking' component={Calendar}/>
Shows the two components for the specified path.
<Route path='/:shop/booking'>
<Aux>
<Services/>
<Calendar/>
</Aux>
</Route>
Shows the two components wrapped in another, for any path.
Finally, I would say that the best practice in React is to wrap your two components into one, and add it to the component prop of a route instead of creating two routes with the exact same path.
If you cannot wrap your two components because one has to be displayed on several routes, you can use something like the following :
<BrowserRouter>
<div>
<Header />
<Switch>
<Route path='/' component={Home}/>
<Route path='/foo' component={Foo}/>
<Route path='/foo2' component={Foo2}/>
</Switch>
<Footer />
</div>
</BrowserRouter>

Prefixing all react links within the app

I have several links throughout my react app that look like this:
<Route path="/linkpath" component={Whatever} />
or
<Link to="/linkpath">Click Me</Link>
Is there a quick/easy way to prefix all the links throughout the app with a predetermined string? ... perhaps via a Router configuration param?
So for example if my prefix is "/foo", all links to "/linkpath" would be converted to /foo/linkpath.
Note: Just to clarify, I'm using react-router-dom v4.0.0-beta.5
It turns out the Router in react-router-dom v4.0.0-beta.5 has a param called basename that addresses this scenario.
<Router basename="/foo">
<Link to="/linkpath">Click Me</Link>
<!-- other links here -->
</Router>
In this case, Click Me's link will be /foo/linkpath. So, as long as Router wraps all Components in the app, all links will be prefixed with basename.
One important note: Make sure the string in basename starts with a slash; i.e., use "/foo" instead of "foo". The latter one produces undesired behavior when clicking links (it appends the full link path to the existing URL everytime you click the link, instead of replacing it).
Using React Router, if you defined your routes using nesting like this:
<Router history={history}>
<Route path="/" component={App}>
<Route path="/hello" component={Hello} />
<Route path="/whatever" component={Whatever} />
</Route>
</Router>
Then you can simply change the path of the outermost Route component and it will add the prefix. In the case above, you could change it to:
<Router history={history}>
<Route path="/api" component={App}>
<Route path="/hello" component={Hello} />
<Route path="/whatever" component={Whatever} />
</Route>
</Router>
And then all the nested routes will be at /api/hello, /api/whatever instead of the original /hello and /whatever.

Resources