I’m trying to use the useLocation
hook in my component:
import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { connect } from 'react-redux';
import { useNProgress } from '@tanem/react-nprogress';
import type { PayloadAction } from '@reduxjs/toolkit';
import type { AppState } from '@/store/app';
import { uiActions } from '@/store/reducers/ui';
import EDProgressBarView from './EDProgressBar.view';
interface IPropsFromState {
readonly isProgressBarVisible: boolean;
}
interface IPropsFromDispatch {
readonly closeProgressBar: () => PayloadAction;
}
interface IProps extends IPropsFromState, IPropsFromDispatch {}
const EDProgressBar: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
const { animationDuration, isFinished, progress } = useNProgress({
isAnimating: props.isProgressBarVisible,
incrementDuration: 200,
});
const location = useLocation();
useEffect(() => {
props.closeProgressBar();
}, [location]);
return (
<EDProgressBarView
animationDuration={animationDuration}
isFinished={isFinished}
progress={progress}
/>
);
};
EDProgressBar.displayName = 'EDProgressBar';
EDProgressBar.defaultProps = {};
const mapStateToProps = (state: AppState) => {
return {
isProgressBarVisible: state.ui.isProgressBarVisible,
};
};
export default connect(mapStateToProps, {
closeProgressBar: uiActions.closeProgressBar,
})(React.memo(EDProgressBar));
And I place this component here:
import React, { Suspense, useMemo } from 'react';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import EDNotification from '@/ui/EDNotification';
import EDProgressBar from '@/ui/EDProgressBar';
import RouterBuilder from './App.router';
interface IProps {
readonly isAuthenticated: boolean | null;
}
const AppView: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
const routes = useMemo(() => {
return RouterBuilder(props.isAuthenticated);
}, [props.isAuthenticated]);
return (
<Suspense fallback={null}>
<RouterProvider router={createBrowserRouter(routes)} fallbackElement={null} />
<div id="backdrop-root" />
<div id="overlay-root" />
<EDNotification />
<EDProgressBar />
</Suspense>
);
};
AppView.displayName = 'AppView';
AppView.defaultProps = {};
export default React.memo(AppView);
So then I get an error:
Uncaught Error: useLocation() may be used only in the context of a <Router> component.
But I don’t understand how can I do such thing if RouterProvider
component does not accept any children of something like a component to inject it.
I need this EDProgressBar
component to exist in the application regardless of the active route. I need it to exist in every page.
How can I do so?