I'm using React Router v5 with a custom history object and redirects aren't working properly. I'm using react-router-dom 5.x ("^5.2.0") and history 4.x ("4.10.1"). My redirects are updating the URL, but not rendering the component without reloading the page.
AppRouter.tsx
import React from "react";
import {Route, Router, Switch} from "react-router-dom";
import {createBrowserHistory} from "history";
import {paths} from "../configs/routerConfigs";
import Main from "../modules/Main";
import Blog from "../modules/Blog"
import Store from "../modules/Store"
import Gallery from "../modules/Gallery";
const history = createBrowserHistory();
const AppRouter = () => {
return (
<Router history={history}>
<Switch>
<Route
path={paths.blog()}
exact
>
<Blog/>
</Route>
<Route
path={paths.store()}
exact
>
<Store/>
</Route>
<Route
path={paths.gallery()}
exact
>
<Gallery/>
</Route>
<Route path={paths.main()} exact>
<Main />
</Route>
</Switch>
</Router>
);
};
export default AppRouter;
this is the header from where I redirect to another link
index.tsx
const AppHeader: React.FC = () => {
return (
<BrowserRouter>
<Header className="app-header">
<Row gutter={16}>
<Col span={6}>
<div className="logo">
<img src={Logo} alt={"cosmonet logo"}/>
<span>Cosmonet</span>
</div>
</Col>
<Col span={12}>
<nav className={"nav"}>
<Menu className="nav-list" mode="horizontal" >
<Menu.Item key="1" className="nav-list-items"><Link to={paths.main()}>{"Main"}</Link></Menu.Item>
<Menu.Item key="2" className="nav-list-items"><Link to={paths.blog()}>{"Blog"}</Link></Menu.Item>
<Menu.Item key="3" className="nav-list-items"><Link to={paths.store()}>{"Store"}</Link></Menu.Item>
<Menu.Item key="4" className="nav-list-items"><Link to={paths.gallery()}>{"Gallery"}</Link></Menu.Item>
</Menu>
</nav>
</Col>
<Col span={6}>
<Button text={"log out"}/>
</Col>
</Row>
</Header>
</BrowserRouter>
);
};
export default AppHeader;
I tried another versions of react-router-dom and history but none of them seems to work properly. I even tried to use forceRefresh: true but it doesn't work either :/
CodePudding user response:
I don't know where the AppHeader
is rendered in relation to the AppRouter
, and vice-versa, but you are using two routers when you need only one routing context for your entire app.
The issue is that any navigation actions by the links in the AppHeader
will be handled by the BrowserRouter
you've used there. The Router
wrapping the routes isn't made aware of any changes, that is until you refresh the page and it remounts and reads the URL path.
I suggest removing the Router
& history
from AppRouter
and the BrowserRouter
from AppHeader
. Move the Router
and custom history
object higher up in the ReactTree to allow providing a routing context to the entire app.
Example:
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from "react-router-dom";
import { createBrowserHistory } from "history";
import App from "./App";
const history = createBrowserHistory();
ReactDOM.render(
<StrictMode>
<Router history={history}>
<App />
</Router>
</StrictMode>,
document.getElementById("root")
);
AppRouter
const AppRouter = () => {
return (
<Switch>
<Route path={paths.blog()} exact>
<Blog/>
</Route>
<Route path={paths.store()} exact>
<Store/>
</Route>
<Route path={paths.gallery()} exact>
<Gallery/>
</Route>
<Route path={paths.main()} exact>
<Main />
</Route>
</Switch>
);
};
AppHeader
const AppHeader: React.FC = () => {
return (
<Header className="app-header">
...
</Header>
);
};