React Redux render the app before axios response

Viewed 70

I need to check auth staues before render the app

i run the action in index.js like this:

import ReactDOM from 'react-dom';
import "bootstrap/dist/css/bootstrap.css";
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './store/index';
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom';
import {authCheckStaut} from './store/actions/auth'

store.dispatch(authCheckStaut());

ReactDOM.render(
  <Provider store={store}>
  <BrowserRouter basename="/">
    <App />
  </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

reportWebVitals();

and this is App page:

import { connect } from 'react-redux';
import { BrowserRouter as Router, Route, Switch, withRouter} from "react-router-dom";
import PrivateRoute from './routes/compoments/PrivateRoute'
import * as actions from '../src/store/actions/auth';




const Login = lazy(() => import("./users/components/login"));

const Signup = lazy(() => import("./users/components/signup"));

const Dashboard = lazy(() => import("./users/components/dashboard"));

const App = (props)=> {

    return (
      <Router>
        <Suspense fallback={<h1>Loading...</h1>}>
          <Switch>
              <Route exact path="/login" component={Login} />
              <Route exact path="/signup" component={Signup} />             
              <PrivateRoute exact path="/" component={Dashboard} auth={props.currentUser} />
          </Switch>
        </Suspense>
      </Router>
    );
  }


const mapStateToProps = state => ({ currentUser: state.auth });
export default withRouter(connect(mapStateToProps, actions)(App));

and this is the PrivetRoute page:

import {Route, Redirect} from 'react-router-dom';

const PrivateRoute = ({component:Component,auth,...rest}) => {
    return (
    <Route 
        {...rest}
        render = {props =>{
            console.log('PR',auth)
            if(!auth.isAuthenticated){
                return <Redirect to={{
                    pathname: '/login',
                    state: { from: props.location }
                }}/>
            } else {
                return <Component {...props}/>
            }

        }}
    />
)};
  
export default PrivateRoute;

I did some console logs to track my app

consol logs

as u can see he update the store state after he render the app, so it will be always redirect to login even it is valid token

1 Answers

React always render current state of your app. What you want is some initial state where you will wait for response. Right now your state transition look like this:

Scheme of two states. Initial state is "Not authenticated". On "Request complete" message there is transition to same  state if actually not authenticated, or to "Authenticated"

What you want, is three states, like this:

Three state schema where there is initial state "Waiting Auth status". When request completed there is transition to "Not authenticated" or "Authenticated" depending on actual authentication status

How to read schemas:

Arrow from nowhere indicates "initial" state. States are in boxes. Arrows from box to box is a transitions. There is names of transitions (events) near arrows. Square brackets indicate "condition" (or transition guard). Transition will happen only if condition is true.

Related