@reach/router - path updates but component doesn't render when Link clicked

675 Views Asked by At

I started using @reach/router for a new project based on a recommendation on the react-router-dom github page. Unfortunately, what seems like a very simple use case is not working. I began by trying to use the @mui BottomNavigation component with the @reach/router Link as follows:

<BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} component={Link} to="/favorites" />

Clicking on the button in the nav does update the URL in the browser, but it does not render the "favorites" component. So I removed a variable and tried routing directly between components:

<Link to="/favorites">Favorites</Link>

and that also failed in the same way, URL updates but the component does not render. I thought about using programmatic navigation with the useNavigation hook provided by @reach/router but that only works within a component that is nested under a Router parent, and my BottomNavigation component is not since it is not addressable via a path. Any thoughts on why this isn't working. Seems like a simple use case.

Here are the relevant details.

AppRoutes.tsx

<Router onChange={(event) => console.log(event)}>
   <LoginPage path="/" />
   <VisitedPage path="/visited" />
   <FavoritesPage path="/favorites" />
   <OptionsPage path="/options" />
   <HousePage path="/house" />
</Router>

BottomNav.tsx

<BottomNavigation
   showLabels
   value={value}
   onChange={(event, newValue) => {
      setValue(newValue);
   }}
>
   <BottomNavigationAction label="Visited" icon={<VisibilityIcon />} component={Link} to="/visited" />
   <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} component={Link} to="/favorites" />
   <BottomNavigationAction label="Options" icon={<SettingsIcon />} component={Link} to="/options" />
</BottomNavigation>

App.tsx

<div>
   <Header />
   <div className="content">
      <AppRoutes />
   </div>
   <BottomNav />
</div>

Example of linking between components:

import { Link, RouteComponentProps } from "@reach/router";

export default function OptionsPage(props: RouteComponentProps) {
    return <Link to="/favorites">Favorites</Link>
}
1

There are 1 best solutions below

0
On

I had the same problem, I solved it by using:

import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './App';

render(<React.StrictMode>
    <App />
</React.StrictMode>, document.getElementById("root"));

instead of:

import React from "react";
import ReactDOM from 'react-dom/client';

import App from './App';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

to render app.

ReactDOM.render is no longer supported in React 18 so I think you should just switch to react router. Alternatively you could use javascript instead of typescript as @react/reach works correctly on it.