0

I have a project structure like that:

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import {store, persistor} from './helpers';
import { Main } from './main';
import { PersistGate } from 'redux-persist/integration/react';
import { InitIDB } from './helpers/InitIDB';

require('./bootstrap');
InitIDB();

render(
    <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
            <Main />
        </PersistGate>
    </Provider>,
    document.getElementById('root')
);

This is entry point, and then the Main component:

import React from 'react';
import { Route, Switch, Router } from 'react-router-dom';
import { connect } from 'react-redux';

import { history } from '../helpers';
import {PrivateRoute} from "../components";
import { ProjectPage } from '../forms/project';
import { ProfilePage } from '../forms/profile';
import { Login } from '../forms/login';

class Main extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <React.Fragment>
                <Router history={history}>
                    <Switch>
                        <Route exact path="/login" component={Login} />
                        <PrivateRoute exact path="/com/projects" component={ProjectPage} />
                        <PrivateRoute exact path="/com/profiles" component={ProfilePage} />
                    </Switch>
                </Router>
            </React.Fragment>
        );
    }
}

function mapState(state) {
    const { alert } = state;
    return { alert };
}

const actionCreators = {
    clearAlerts: function() {}
}

const connectedApp = connect(mapState, actionCreators)(Main);
export { connectedApp as Main };

//PrivateRoute

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import {LayoutX} from '../forms/layout';

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        sessionStorage.getItem('user')
            ? <LayoutX><Component {...props} /></LayoutX>
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
    )} />
)

I want when user access private route, before that the program will send a request to server and it will return a response decide user can be access this page or not. I try to send a request with axios in PrivateRoute but it is async request and I can not get response before render. What should I do?

May'Habit
  • 866
  • 7
  • 13
  • 1
    Does this answer your question? [Simple Conditional Routing in Reactjs](https://stackoverflow.com/questions/48497510/simple-conditional-routing-in-reactjs) – GalAbra Apr 16 '20 at 14:46
  • Using api call while navigating to the route is not a good option. Get user permissions, persist in localSotorage and then write code to determine if you need to allow the user to access that page or redirect – Zohaib Ijaz Apr 16 '20 at 14:46
  • @Zohaib Ijaz I know it's hard but I have no choice – May'Habit Apr 16 '20 at 14:53
  • @GalAbra i'm going to try Redirect in entry point in the next day, I hope this will work – May'Habit Apr 16 '20 at 15:00

1 Answers1

-1

Your PrivateRoute should block render when waiting for the authentication status from API is returned.

You can take a look at a simple implementation of PrivateRoute I wrote in this codesandbox.

enter image description here

Jackyef
  • 3,473
  • 14
  • 22
  • I always think what I try there is something like server render, this is hard to do with client render. Your solution dont resolve my problem but I think this is the best suggestion until now so I'm going to accept your answer. Thanks. – May'Habit Apr 16 '20 at 15:40
  • If you are doing server render, you can do the authentication on the server side before rendering. You can serialise this data and inject it to your HTML response. Then, on the client side you can use the injected data as the initial state of the app. – Jackyef Apr 16 '20 at 15:41
  • No, i'm backend developer but I must to write reactjs app. With server render, its to easy for me. But with client render, in my case, I have to send request to check role for every route. – May'Habit Apr 16 '20 at 15:49
  • Someone wants me do that, I dont want but I have no choice – May'Habit Apr 16 '20 at 15:50