So here's the situation - When a Link
is clicked the nprogress bar will start and I want react-router to only replace the current component with the matched route once that's done loading asynchronously.. just like in instagram..
But I am only getting this -
Here's my HOC to load component asynchronously --
import React, { useEffect, useState } from "react";
import nprogress from "nprogress";
import "nprogress/nprogress.css";
export default importComponent => props => {
const [loadedComponent, setComponent] = useState(null);
// this works like componentwillMount
if (!nprogress.isStarted()) nprogress.start();
if (loadedComponent) nprogress.done();
useEffect(() => {
let mounted = true;
mounted &&
importComponent().then(
({ default: C }) => mounted && setComponent(<C {...props} />)
);
// componentUnMount
return () => (mounted = false);
}, []);
// return the loaded component
const Component = loadedComponent || <div style={{ flexGrow: 1 }}>..</div>;
return Component;
};
I didn't find a solution to this anywhere on the internet.. so I am asking this question here in stackoverflow. I am hoping someone here can solve this.
Edit: 15-Nov-2021
The old approach doesn't work with routes that uses route params or query such as useLocation, useRouteMatch, etc.
The one I am using now is to use React.lazy, React.Suspense and updating the fallback prop whenever a page is rendered. So when the next page is being loaded, the fallback will be shown which is basically the same component instance as current page. Moreover, with this new approach, you can render the next page whenever you like; after fetching data from backend, or after animation, etc.
Here is a demo and source code.