When I click on a Nav.link in my SPA application the entire page re-renderss, but I only want the content in the main portion of the UI to change based on the link being clicked. In the layout I have a header nav and then one row and two columns. The content of the header nav never changes, and the left column is a static list of clickable Nav links. The only content I want to change is the content of the right column based on the link that is clicked, and I do not want to re-render the entire app, just the content of the column.
App.js
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(
<React.StrictMode>
<BrowserRouter>
<CommonComponent/>
</BrowserRouter>
</React.StrictMode>
);
CommonComponent
<>
<Navbar>
<div></div>
</Navbar>
<Container fluid>
<Row>
<Col xs={4} sm={4} md={4} lg={3} xl={2}>
<Nav.Item href="/a">
<Nav.Link href="a">Comp A</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link href="b">Comp B</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link href="c">Comp C</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link href="d">Comp D</Nav.Link>
</Nav.Item>
</Col>
<Col xs={8} sm={8} md={8} lg={9} xl={10}>
<Routes>
<Route path="/" element={<Navigate to="a" replace />} />
<Route path="/a" element={<CompA {...props} />} />
<Route path="/b" element={<CompB {...props} />} />
<Route path="/c" element={<Compc {...props} />} />
<Route path="/d" element={<CompD {...props} />} />
</Routes>
</Col>
</Row>
</Container>
</>
The CompA, CompB, etc, are just different forms, nothing complicated. However any click on the side nav links renders the entire app.
I believe the issue is that the Nav.Link
component renders a raw anchor tag by default. You want to render a react-router-dom
Link
component though.
Try importing the Link
from react-router-dom
and rendering that as the Nav.Link
component.
See Nav.Link props.
Pass the Link
to the Nav.Link
component's as
prop and change href
to to
for the Link
component's target. You'll probably also want to use absolute paths.
Example:
import { Link, Routes, Route } from 'react-router-dom';
...
<>
<Navbar>
<div></div>
</Navbar>
<Container fluid>
<Row>
<Col xs={4} sm={4} md={4} lg={3} xl={2}>
<Nav.Item href="/a">
<Nav.Link as={Link} to="/a">Comp A</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={Link} to="/b">Comp B</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={Link} to="/c">Comp C</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link as={Link} to="/d">Comp D</Nav.Link>
</Nav.Item>
</Col>
<Col xs={8} sm={8} md={8} lg={9} xl={10}>
<Routes>
<Route path="/" element={<Navigate to="/a" replace />} />
<Route path="/a" element={<CompA {...props} />} />
<Route path="/b" element={<CompB {...props} />} />
<Route path="/c" element={<Compc {...props} />} />
<Route path="/d" element={<CompD {...props} />} />
</Routes>
</Col>
</Row>
</Container>
</>