Routing an OR path with React-Router - react-router

I'm routing pages that maintain the same component structure, but their content changes slightly based on the URL. When setting up my routes for this area I'm currently using the following structure:
<Route path="/:focusPath/read/agree" component={ViewerLayout} />
<Route path="/:focusPath/read/neutral" component={ViewerLayout} />
<Route path="/:focusPath/read/disagree" component={ViewerLayout} />
<Route path="/:focusPath/speak/agree" component={ViewerLayout} />
<Route path="/:focusPath/speak/neutral" component={ViewerLayout} />
<Route path="/:focusPath/speak/disagree" component={ViewerLayout} />
However, this seems repetitive and overly complex. Though it works as is, is there a way I could reshape it to accomplish something like this?
<Route path={"/:focusPath"+("/read"||"/speak")+("/agree"||"/neutral"||"/disagree")} component={ViewerLayout} />
I realize that the syntax is all wrong, but maybe something that simplifies the 6 lines it took to make it work?

This isn't recommended, but it should work for your use case. You can pass a Regex to path. Here's a snippet that will get you the right idea.
<Route path="/:focusPath/read/(/agree|neutral|disagree/)" component={ViewerLayout} />
I'm rubbish at Regex so that probably won't work as is, but you get the idea.

Related

Why is my last route overriding the css in previous routes?

I am building a simple React SPA personal website, and noticed that CSS selectors for routes that are later in the router are overriding previous ones, even when those later routes are not the page in question. For example, here is my app
function App() {
return (
<div className='App'>
<Router>
<NavBar />
<Routes>
<Route path='/' element={<Home />} exact></Route>
<Route path='/contact' element={<Contact />}></Route>
<Route path='/resume' element={<Resume />}></Route>
<Route path='/projects' element={<Projects />}></Route>
</Routes>
</Router>
</div>
);
}
However, styling for the contact page is being override by the resume page. For example: font-size being overriden
I realize I can use class names for higher specificity, but was wondering what is the root cause of this behavior?
Use different classes for each h1 tag. all CSS files classes and styles work for all components if imported once at any file. so just change CSS and remember to use unique classname for all element you want to style.

React Router with mix of Fixed Routers and Dynamic Route

I am having routes like
/: Login
/A: A Component
/:[dynamic] : B Component
Now I am using code Like below, but now every time Component B is loading, even if i pass "Exact" keyword too.
<Route exact path="/">
<LoginComponent />
</Route>
<Route exact path="/:dynamic" component="Dynamic' />
<Route exact path="/A" component="A" />
this happens because the router can not distinguish between the dynamic value or "A" or "".
as I know you can't solve it without make another route for B component, like "/basicPath/:dynamic"

Does react-router-v4 supports dynamic routing?

I tried to add routes dynamically by using v3 but it didn't support it. React-router-v4 supports dynamic routing or not?
It's quite unclear to me what you actually mean by dynamic routing? Are you thinking of routes provided by the API, or any sort other external source?
Sure you can, but you got to think your structure through. The easiest way to achieve that is to map them inside of your Switch Component:
<Switch>
{ routesList.map((route) => (
<Route
key={route._id}
path={route.path}
component={route.component}
{...route.props} // some custom props, maybe?
/>
)
)}
<Route path='/' component={HomePage} />
<Route path='/about' component={About} />
</Switch>

Accessing URL params in parent components

I've got an interesting conundrum that I'd like some insight on. I've got a routing setup like follows:
<Router history={hashHistory}>
<Route path='/' component={Main}>
<IndexRoute component={Home} />
<Route path='foo' component={FooContainer}>
<Route path='bars/:barId' component={BarDetailsContainer} />
<Route path='baz/:bazId' component={BazDetailsContainer} />
</Route>
<Route path='things' component={ThingListContainer}>
<Route path='thing/:thingId' component={ThingDetailsContainer} />
</Route>
</Route>
</Router>
And it works by and large. FooContainer has a child of its own (not via this.props.children), which wants to know what :barId is (and :bazId) when those components are loaded via their respective routes. Is there a way to access all of the current params -- including the URL params for its child routes -- from the "parent" component, FooContainer?
Note: it is also possible that I am doing this entirely wrong, in which case, I would love some advice on a better way to accomplish my goal here.
An answer, for those concerned:
Turns out I was looking for this.props.params in a child of Main that is not managed by any Route, and as such, I'd need to explicitly pass the params prop (or whichever params are important) down to it from Main.
My Main's implementation, as a rough JSX sketch, looks like:
<div>
<SomeOtherComponentThatWantsParams />
{this.props.children}
</div>

How to know what component was created using React Router?

I have the following routes:
<Route path="/" component={App}>
<IndexRoute components={Home}/>
<Route path="/blog/:blogNo/:filter" component={Home}/>
<Route path="/blog/:blogNo" component={Home}/>
<Route path="/:filter" component={Home}/>
<Route path="/all" component={Home}/>
<Route path="/terms" component={Terms}/>
<Route path="/privacy" component={Privacy}/>
<Route path="/news/:newsNo" component={News}/>
<Route path="/list/:listNo" component={List}/>
</Route>
Notice 4 of the routes are Home. In the render of my App.js I want to figure out which component is created, i.e. Home, News, Terms, Privacy, or List.
I'm trying to use this.context.router.isActive("") but I'm not sure how to pass a splat or wildcard like :filter or :blogNo to the function.
How do I know which component is created in React Router?
Note I am using react router 2.0.0
For your menu example, you'll want to follow the named components documentation. That pattern is designed to allow having a separate menu component, exactly as you've described your situation.