Home > Enterprise >  App redirect to root inside axios interceptor with reducer dispatch
App redirect to root inside axios interceptor with reducer dispatch

Time:07-20

My app have this structure.

enter image description here

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>
  );
}
  • Related