I am stuck on this problem for days and the solutions that I find on the web are not helpful. My routes are not working properly. The URI is updating, but the appropriate pages are not displaying according to the path. When I refresh the browser, only then, the appropriate page comes through. Otherwise, only the home page is displayed, even when the path changes.
I will do my best to exhaust the codes here:
package.json
...
"history": "^5.3.0",
"node-sass": "^8.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
...
AppRoutes.js
import { useRoutes } from 'react-router-dom';
...
const AppRoutes = () => {
const routes = useRoutes([
{ path: PATH.home, element: <page.Home /> },
{ path: PATH.defect, element: <page.Defect /> },
{ path: PATH.other, element: <page.Other /> },
{ path: PATH.allRoutes, element: <page.Home /> }
]);
return routes;
}
Navbar.js
...
import history from '../../utils/BrowserHistory';
...
/**
* I am using semantic UI menu
* Here I push the path for a browser route change
*/
handleItemClick = (e, { name }) => {
this.setState({ activeItem: name });
switch (name) {
case APP_CONST.home:
history.push(PATH.home);
break;
case APP_CONST.defect:
history.push(PATH.defect);
break;
case APP_CONST.other:
history.push(PATH.other);
break;
default:
history.push(PATH.home);
break;
}
}
...
render() {
const { activeItem } = this.state;
return (
<Fragment>
{
this.state.width <= NUMBER.mobileScreenSize ?
<MobileNav
onToggle={this.handleToggle}
visible={this.state.visible}
onPusherClick={this.handlePusher}
item={activeItem}
handleItemClick={this.handleItemClick}
>
<NavBarChildren>{this.props.children}</NavBarChildren>
</MobileNav> :
<DesktopNav item={activeItem} handleItemClick={this.handleItemClick}>
<NavBarChildren>{this.props.children}</NavBarChildren>
</DesktopNav>
}
</Fragment>
)
}
}
const NavBarChildren = props => (
<Container>{props.children}</Container>
);
DesktopNav.js
export const DesktopNav = props => {
const { item, handleItemClick, children } = props;
return (
<React.Fragment>
<Menu fixed='top' pointing secondary>
<Menu.Menu>
<MenuItems item={item} handleItemClick={handleItemClick} />
</Menu.Menu>
</Menu>
<div className='desktop-menu-items'>{children}</div>
</React.Fragment>
);
}
App.js
imports ...
function App() {
return (
<NavigationBar>
<AppRoutes />
</NavigationBar>
)
}
index.js
...
import { BrowserRouter } from 'react-router-dom';
import history from './utils/BrowserHistory';
...
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter history={history}>
<App />
</BrowserRouter>
);
Please assist, thanks in advance...
The BrowserRouter
doesn't consume a history
prop. The BrowserRouter
maintains its own internal history
reference, and so isn't aware of the URL changes your custom history
object makes.
If you are effecting navigation actions from the custom history
object in that Navbar
component instead of using Link
components then you'll need to use a router that can take the custom history
object so it can synchronize the routes it manages with the URL changes the history
object effects.
You can import the HistoryRouter
, which does consume a history
prop.
Example:
...
import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom';
import history from './utils/BrowserHistory';
...
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<HistoryRouter history={history}>
<App />
</HistoryRouter>
);