Извините, если это что-то очень простое, что я пропускаю, но я пытаюсь создать компонент, который в основном ограничивает определенные маршруты реакции-маршрутизатора только для пользователей, имеющих активный токен.

import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';

function isLogin(){
    const result = Axios.get('http://localhost:8081/authentication', {withCredentials: true})
    .then(res => {
        console.log(res);
    })
    console.log(result);
}

const PrivateRoute = ({component: Component, ...rest}) => {

    return (
        <Route {...rest} render={props => (
            isLogin() ?
                <Component {...props} />
            : <Redirect to="/login" />
        )} />
    );
};

export default PrivateRoute;

Кажется, что (как и ожидалось) только «console.log (result)» выполняется с ожидающим обещанием, но в конечном результате я пытаюсь закодировать некоторую логику в ответ, полученный от моего бэкэнда (true или false), который затем должен быть отправлен в компонент PrivateRoute, чтобы определить, следует ли отправить пользователя обратно для входа в систему и т. д.

Я понимаю, что это должно быть из-за асинхронной природы axios.get, которая вызывает мои проблемы, но я пробовал несколько различных методов:

Сделав функцию isLogin асинхронной, затем дождитесь запроса axios

Создайте еще одну функцию внутри возврата PrivateRoute, которая является асинхронной, с ожиданием.

Кажется, что все, что я пытаюсь здесь сделать, - это не правильно ждать результата от axios.get, и, следовательно, за то, что оно дает нежелательные результаты.

Спасибо.

0
dylanelliott27 20 Дек 2019 в 20:30

2 ответа

Лучший ответ

Как сказал @Emile Bergeron в комментариях (ссылка), я бы добавил состояние в частный компонент Route, который будет сохраняться, если пользователь аутентифицирован. Это будет проверено, когда компонент (частный маршрут) монтируется в первый раз.

Как код, это будет выглядеть примерно так с вашим кодом в качестве основы:

import Axios from "axios";
import React, {useState, useEffect, useSelector} from 'react';
import {Route, Redirect} from 'react-router-dom';

const PrivateRoute = ({component: Component, ...rest}) => {
    // State
    const [authenticated, setAuthentication] = useState(null);
    const [loadingComplete, setLoadingComplete] = useState(false);
    // Login function
    useEffect(
        () => {
            // ComponentDidMount
            // Declare Function (you can also declare it outside the useEffect, 
            //    if you want to run it also if another prop changes for instance.
            //    But it will be overwritten on every rerender; 
            //    To prevent this you could use useCallback hook)
            const isLogin = async () => {
                try {
                    const result = await Axios.get('http://localhost:8081/authentication', {withCredentials: true});
                    // Store the result, e.g. ID, token, ...
                    setAuthentication(result);
                } catch (e) {
                    // Something failed
                    console.log(e);
                }
                setLoadingComplete(true);
            }   
            // run login function
            isLogin();
        },
        []
    );
    if(loadingComplete){
        return (
            <Route {...rest} render={props => (
                !!authenticated ?
                    <Component {...props} />
                : <Redirect to="/login" />
            )} />
        );
    }else{
        return ( <div> Loading... </div>);
    }
};

export default PrivateRoute;

Изменить: Конечно, вам также понадобится состояние для процесса загрузки, так что перенаправление не ударит вас, пока пользователь не будет выбран.

0
Mika 20 Дек 2019 в 17:57