I am having a hard time understanding how to route using a sidebar and conditionally reloading the state. what I mean is that I would like when a route in the sidebar is chosen, data for that route is loaded into the main container to the right of the sidebar.
When clicking on a couple routes, I would like the user to be able to go back to the previous route, without having to re-fetch the data. I know how to lift the state and that works for not re-fetching on page back. The issue is when the link is clicked again, purposefully, I WOULD like the data to be re-fetched but the old state is shown instead.
Approach 1 lifted state:
- Main container component is loaded, data for each route is manually fetched (inefficient but was testing)
- State is then passed to route in said component
- Can go back and forward without reloading.
- Clicking on "Hone" after being on "Item", nothing is re-fetched, old data always displayed.
Approach 2 state in component:
- Routes are loaded on routing on when sidebar items are clicked.
- Fetch handled locally in component
- Going back or forward re-fetches
- Clicking on "Hone" after being on "Item", will re-fetch the data as intended.
I have tried so many different ways, but I can only ever hold the state indefinitely or fetch on back each time. No hybrid fetching and state caching as I would like. Been at this for the last two days and I give up. The code is below with the component based local state/constant route re-fetching. Any help would be greatly appreciated.
Main Container
import React from "react";
import SideBar from "./Sidebar";
import Header from "./Header";
import Routes from "./Routes";
function MainContainer() {
return (
<>
<div className="main-sidebar">
<SideBar />
</div>
<div className="main-content">
<Header />
<Routes />
</div>
</>
);
}
export default MainContainer;
Sidebar
import React from "react";
import { NavLink } from "react-router-dom";
import Nav from "react-bootstrap/Nav";
function SideBar({ onClick }) {
const linkItems = [
{ name: "Home", to: "/" },
{ name: "Item", to: "/item" },
{ name: "Dashboard", to: "/dashboard" },
];
const sidebarItems = linkItems.map((item) => (
<Nav.Item key={item.to}>
<NavLink exact to={item.to} activeClassName="sidebar-active-nav" className="nav-link sidebar-inactive-nav">
<h3>{item.name}</h3>
</NavLink>
</Nav.Item>
));
return <Nav className="flex-column">{sidebarItems}</Nav>;
}
export default SideBar;
Routes
import React from "react";
import { Switch, Route } from "react-router-dom";
import Dashboard from "./Dashboard";
import Item from "./Item";
import Home from "./Home";
function Routes() {
return (
<div className="container-fluid">
<Switch>
<Route path="/" exact render={(props) => <Home key="1" {...props} />} />
<Route path="/item" render={(props) => <Item key="2" {...props} />} />
<Route path="/dashboard" render={(props) => <Dashboard key="3" {...props} />} />
</Switch>
</div>
);
}
export default Routes;
Example of a route component
import { useEffect } from "react";
import Component from "react-bootstrap/Container";
import Spinner from "react-bootstrap/Spinner";
import useFetch from "../helpers/Fetcher";
function Dashboard() {
const [data, loading] = useFetch("https://raw.githubusercontent.com/epicmau5time/demo/master/test.json");
useEffect(() => {
return () => {
console.log("cleaned up");
};
}, []);
return (
<Component className="page-container">
<h2>Dashboard</h2>
{!loading && data ? (
data.map((data) => (
<div key={data.id}>
<p>{data.title}</p>
</div>
))
) : (
<div className="justify-content-center text-center">
<Spinner className="" animation="border" variant="primary" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
</div>
)}
</Component>
);
}
export default Dashboard;
Fetching helper