Currently I'm trying to make it so that my parent router is activated each time. I'm not very sure of the terminology here.
<BrowserRouter>
<Switch>
<Route exact path='/browserRouterPath' component={loginComponent}/>
<HashRouter>
<Route path='/hashRouterPath' component={loginComponent2}/>
<Route path='/' component={loggedInComponent}/>
</HashRouter>
</Switch>
</BrowserRouter>
LoggedInComponent
<Switch>
<Route exact path='/' render={() => (
<Redirect to: {{pathname: '/finalComponent'> }}/>
)}> />
...
</Switch>
My current problem is that my components in the hashRouter are not being called.
When the loggedInComponent redirects it to the new path, the hashRouter is not called.
However, if I remove the hashRouter in the first block of code. The hashRouter is called without incident, but that breaks the CSS/styling of the components in the program.
Is there a way to render the parent component each time? Or is there a workaround that eliminates the hashRouter but keeps the CSS for me?
Related
I think that the problem is in the switch, in version of react-router-dom or in routes. Only when I created and applied the code in this class, the screen started don't render and stays white. I already changed the version of react-router-dom but I don't know what can be.
Below the code of routes.js:
//react-router-dom version: "^5.3.0"
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Home from './pages/Home';
import Header from './components/Header';
const Routes = () => {
return(
<BrowserRouter>
<Header/>
<Switch>
<Route exact path="/" component={Home}/>
</Switch>
</BrowserRouter>
)
}
export default Routes;
React Router v6 introduces some changes like.
Routes component that is kind of like Switch, but a lot more powerful one.
Route still exist but you don't pass a pointer to that component function or as a children component, Instead you pass the JSX element to the element prop &
exact doesn't exist anymore, now it's always looks for exact matches.
So, component={Home} would become element={<Home />}
Something like this
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
</Routes>
You can dive deep to this migration guide: https://reactrouter.com/docs/en/v6/upgrading/v5
hope that's help you
I have been trying to change the route of react application with react-router-dom
<Switch>
<Route path="/id" component={Random}/>
<Route path="/" exact component={Products}/>
</Switch>
Inside the application when I am using /id in the URL it is rendering Products Component instead of Random Component
Inside index.js the code is:
ReactDOM.render(
<BrowserRouter><Products/></BrowserRouter>,document.getElementById("root")
);
You should be rendering your router. You are currently rendering the product component
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/id" component={Random}/>
<Route path="/" exact component={Products}/>
</Switch>
</BrowserRouter>,document.getElementById("root")
);
You should render the Switch component inside BrowserRouter tag.
This is my router structure:
<Router>
<main className="py-3">
<Switch>
<Container>
<Route exact path="/admin" component={AdminScreen}></Route>
<Route path="/:campaignId" component={CampaignScreen}></Route>
<Route path="/" component={HomeScreen} exact></Route>
</Container>
</Switch>
</main>
</Router>
For "some" reason, when I go to /admin i also get the CampaignScreen rendered.
I added the <Switch> as you can see, but it does not seem to help.
Where lies the problem?
Since admin can theoretically also be a campaignId react router thinks it matches both routes, and you have the <Container> element directly inside the Switch it still renders both, the solution is to have your routes directly in the Switch
I have been searching, and trying for a while now, however I couldn't find an answer if it is possible to use MemoryRouter for only specific routes while I use BrowserRouter in general. I wan t to navigate to a certain component but not change the url, tried it like so, but it changes the url but not rendering the component, the complete opposite what I wish.
<BrowserRouter>
<Switch>
<Route path="/login" component={Login} exact />
<Route path="/" component={MainPage} />
<MemoryRouter>
<Route
path='/somecomponent'
component={SomeComponent}
/>
</MemoryRouter>
</Switch>
</BrowserRouter>
Routes inside the MemoryRouter are relative to the MemoryRouter, not to your current location as displayed in the URL bar.
As far as it's concerned, the current route is "/", and it will only render components at <Route path="/">. If you were to add
<Route path="/">
<Redirect to="/somecomponent" />
</Route>
directly under MemoryRouter it should go to the path you're looking for, and render as intended.
I have a situation where few routes consists of the same component and I want to preserve its state, but with this behavior it's fairly impossible.
Live example (look at seconds elapsed):
https://csb-43lp1km647-nkiinaibit.now.sh
CodeSandbox:
https://codesandbox.io/s/43lp1km647
Of course I could save and restore state of timer while changing routes, but my app has an infinite CSS transition as a background (not on every route).
I was trying adding keys, even portal, but it still remounts everything.
Is there any way to enforce typical React's reconciliation (remount only elements that have to be remounted)?
Update:
Just found out that <Switch /> will render everything until it finds element that matches, and that could be either a certain <Route /> or any element except it's inside <Fragment />.
Code:
<Router history={history}>
<Switch>
<Route path="/third" component={RouteWithoutTimer} />
<React.Fragment>
<Timer />
<Route exact path="/" component={FirstRoute} />
<Route path="/second" component={SecondRoute} />
</React.Fragment>
</Switch>
</Router>
Or with wildcard route:
<Router history={history}>
<Switch>
<Route path="/third" component={RouteWithoutTimer} />
<React.Fragment>
<Timer />
<Switch>
<Route exact path="/" component={FirstRoute} />
<Route component={NotFoundRoute} />
</Switch>
</React.Fragment>
</Switch>
</Router>
It's not a solution I was looking for, but it works fine.
You are mounting a new instance of Timer in each route.
If you want to share a component across routes, you should lift it to the parent component of the routes:
<React.Fragment>
<Timer />
<Switch>
<Route exact path="/" component={FirstRoute} />
<Route path="/second" component={SecondRoute} />
</Switch>
</React.Fragment>
This is where the state management libraries come to scene.
In React, states are per component and has lifecycle of it's owned component, so when router destructs/remounts the component, you lose all the data. I advice you to migrate your state to a state management library like redux as soon as possible. Otherwise your code can be mess if this is a medium-sized application.