Реагировать на проблему мерцания аутентификации при изменении маршрута - PullRequest
0 голосов
/ 01 июля 2018

Я создаю несколько приложений в react, последним является панель администратора, поэтому мое приложение react должно иметь аутентификацию, абсолютно все мои продукты использовали Server Side Rendering.

В последнем случае серверная команда использует pass me Token для обработки авторизации, это технологии Java, Spring, Redis и т. Д. Base.

Когда я отправляю username и password на их сервер, если информация верна, они отправляют мне token и что-то еще, я сохраняю ее в localStorage и меняю корень state из react приложение в качестве логина, из-за этого изменения приложения используют другой routing.

Все выглядит хорошо, но что происходит, когда я обновляю страницу? здесь проблема возникнет, login state равно false, поэтому приложение переходит на страницу входа в систему, в componentDidMount я прочитал localStorage и выяснил О-о! Я получил токен раньше и приложение вошло в систему, поэтому измените login state на true.

ЗДЕСЬ , мерцание происходит, и я не знаю, как я могу предотвратить это плохое событие.

Мой корень state, как показано ниже:

class App extends Component {

    constructor() {
        super();

        this.state = { //the root state
            login: false,
        };

    };
    ...

componentDidMount как показано ниже:

componentDidMount() {
    this.loginStateHandler(!!JSON.parse(localStorage.getItem('accessToken')));
};

loginStateHandler = (login) => {

    if (!login) {

        localStorage.clear();
    }

    this.setState({
        login,
    });
};

А переключение между маршрутом входа в систему и маршрутом приложения выполняется в render функции корневого компонента с именем App, см. Код ниже:

        {
            this.state.login
                ? (
                    <div className={styles['app-wrapper']}>
                        <div className={styles['app-wrapper__top']}>
                            <Button classes={{root: this.props.classes.exitButton}} onClick={this.logoutHandler}>
                                exit
                            </Button>
                        </div>
                        <AppRoutes key='appRoutes' fetchManager={this.fetchManager}/>
                    </div>
                )
                : (
                    <LoginRoutes loginHandler={this.loginHandler}/>
                )
        }

Как я могу написать аутентификацию, которая предотвращает это мерцание. Я хочу, чтобы приложение решило, что пользователь вошел в систему или нет перед первым рендерингом. это возможно?

Ответы [ 3 ]

0 голосов
/ 01 июля 2018

Вместо этого вы можете поместить всю эту логику прямо в constructor, чтобы ваша login переменная в вашем состоянии сразу же была правильной:

class App extends Component {
    constructor() {
        super();

        const login = !!JSON.parse(localStorage.getItem('accessToken');

        if (!login) {
            localStorage.clear();
        }
        this.state = { login };
    }
}
0 голосов
/ 04 июля 2018

Я только что нашел очень хороший способ, сначала я render null в функции рендеринга компонента login, а затем вставил следующий код в componentDidMount метод жизненного цикла:

setTimeout(() => {
    if (!JSON.parse(localStorage.getItem('loginDetails'))) {
        this.setState({
            renderDOM: true,
        })
    }
}, 0);

Это означает, что, если приложение не выполнит вход в систему, отобразите компонент login, из-за использования setTimeout условие исчезнет с call stack, а затем после очистки stack условие перейдет к stack, поэтому для этого огромная задержка при входе в приложение, вы никогда не увидите мерцание страницы входа.

Но в этом пути есть что-то, может быть, я думаю, это может быть проблема SEO, когда кто-то входит в систему и напрямую вызывает какую-то страницу, например website.com/users-list-page/, а затем в первое приложение переходит на login компонент и логин component рендер null then app read the localStorage and find out oOH!, I'm logged-in so setState to логин true , then app goes to страница списка пользователей with related component, but _remember_, the логин page is rendered in server as ноль and because of the app was logged-in, the call back function of setTimeout doesn't run anything, so when the users-list-page appear pressing <kbd>Ctrl</kbd>+<kbd>U</kbd> to show page HTML` исходники, вы ничего не видите в

<div id="root"></div>

Это может быть причиной SEO проблем. Не знаю, может, у кого-то есть идея?

Возможно, есть другой способ избежать мерцания, а затем визуализировать users-list-page DOM с сервера. Понятия не имею пока. ☹️

0 голосов
/ 01 июля 2018

общая схема - задержка рендеринга до тех пор, пока вы не прочитаете состояние входа пользователя из LocalStorage

например, в Redux есть постоянная библиотека Redux, в которой хранится избыточное состояние, поэтому она сохраняется при обновлении страницы

недавно они добавили HOC для ожидания загрузки локального состояния
https://github.com/rt2zz/redux-persist/blob/master/docs/PersistGate.md

вы можете видеть, что этот HOC имеет опцию загрузки компонента, поэтому он отображает ее до тех пор, пока не будет загружено локальное состояние

Я предлагаю вам сделать то же самое с некоторой логикой для ожидания / отображения загрузки до тех пор, пока не будет загружено локальное хранилище

...