My app have this structure.
I'm using a reducer atached in Axios to when axios do any API request my overlay show "loading" page. Its all ok when I not using routes. When I to do any API request inside a route I'm redirected to root route.
My interceptor
axios.interceptors.request.use(async config => {
let user = userStore && userStore?.auth?.user
config.headers.Authorization = `Bearer ${user.accessToken}`
dispatcher.dispatch('isLoading', true) // the problem is tihis line
return config;
})
App.js
import LoadingOverlay from 'react-loading-overlay';
import { dispatcher } from 'react-dispatch'
const App = (props) => {
const { theme } = useTheme();
const [isLoadingAxios, setLoadingAxios] = useState(false);
const [isLoggedIn, screen,] = useState({
isLoggedIn: false,
screen: []
});
LoadingOverlay.propTypes = undefined
useEffect(() => {
dispatcher.on('isLoading', res => setLoadingAxios(res));
return () => {
dispatcher.off('isLoading')
}
}, [])
const MyAppRouter = () => {
const [userStore] = useUserStoreContext()
return userStore && userStore?.auth?.Authenticated ?
<MemoryRouter >
<AppRoutes />
</MemoryRouter>
: <LoginPage />
}
return (
<>
<ThemeProvider theme={theme}>
<GlobalStyles />
<LoadingOverlay
active={isLoadingAxios}
spinner text='Loading...'>
<UserStoreProvider>
<CoreStoreProvider>
<MyAppRouter />
</CoreStoreProvider>
</UserStoreProvider>
</LoadingOverlay>
</>
);
}
export default App;
Routes.js
const AppRoutes = (props) => {
return (
<Routes>
<Route path='' element={<MainPage id={uuidv4()} theme={props.theme} />} >
<Route path='dashBoard' element={<DashBoardView id={uuidv4()} />} />
<Route path='statement' element={<StatementsView id={uuidv4()} />} />
<Route exact path='/' component={props => <DashBoardView id={uuidv4()} />} />
</Route>
<Route path="*" component={() => '404 NOT FOUND'} />
</Routes>
);
}
export default AppRoutes
Requests inside 'statement' rediret the app to '' route. If I remove dispatch in interceptor I dont redirected.
I debug MyAppRouter and n dispacth the component is redrawed but the values is not changed. This arquitecture is wrong or I need "cache" cuurent route to avoid this redirect?
I'm using v18.2 of react.
Tks
CodePudding user response:
You should not declare/define React components inside other React components. Each time App
rerender (for any reason) the MyAppRouter
will be redeclared and remount its entire sub-ReactTree.
Move MyAppRouter
outside the App
component.
Example:
import LoadingOverlay from 'react-loading-overlay';
import { dispatcher } from 'react-dispatch';
const MyAppRouter = () => {
const [userStore] = useUserStoreContext();
return userStore && userStore?.auth?.Authenticated
? (
<MemoryRouter >
<AppRoutes />
</MemoryRouter>
) : <LoginPage />;
}
const App = (props) => {
const { theme } = useTheme();
const [isLoadingAxios, setLoadingAxios] = useState(false);
const [isLoggedIn, screen,] = useState({
isLoggedIn: false,
screen: []
});
LoadingOverlay.propTypes = undefined;
useEffect(() => {
dispatcher.on('isLoading', res => setLoadingAxios(res));
return () => {
dispatcher.off('isLoading')
}
}, []);
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
<LoadingOverlay
active={isLoadingAxios}
spinner text='Loading...'
>
<UserStoreProvider>
<CoreStoreProvider>
<MyAppRouter />
</CoreStoreProvider>
</UserStoreProvider>
</LoadingOverlay>
</ThemeProvider>
);
}