React Redux с перехватами - аутентификация и защищенные маршруты - PullRequest
1 голос
/ 20 марта 2020

Я использую React с ловушками, response-redux и redux-thunk, и я не уверен, правильно ли я произвел аутентификацию. В Main. js Я вызываю действие под названием checkIfLoggedIn(). Это главное. js содержимое:

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

    }

    render() {
        return (
            <BrowserRouter>
                <div style={{position: 'relative'}}>
                    <Navbar/>
                    <div className={'container-fluid'}>
                        <Route exact path={'/'} component={(Dashboard)}/>
                        <Route exact path={'/sale'} component={(Sale)}/>
                        <Route exact path={'/settings'} component={(Settings)}/>
                        <Route exact path={'/login'} component={(Login)}/>
                    </div>
                </div>
            </BrowserRouter>
        )
    }
}

const mapDispatchToProps = {
    checkIfLoggedIn
};

export default connect(null, mapDispatchToProps)(Main);

Это код checkIfLoggedIn()

import {SET_ADMIN, SET_LOGGED_IN} from "./types";
import axios from 'axios';

export const checkIfLoggedIn = () => async dispatch => {
    const adminToken = window.localStorage.getItem('admin_token');
    if (adminToken === null)
        dispatch({
            type: SET_LOGGED_IN,
            payload: false
        });
    else {
        try {
            const r = await axios.get('/users/me');
            const data = r.data;
            dispatch({
                type: SET_ADMIN,
                payload: data
            });
            dispatch({
                type: SET_LOGGED_IN,
                payload: true
            });

        } catch (e) {
            dispatch({
                type: SET_LOGGED_IN,
                payload: false
            });
        }
    }
};

И мое начальное состояние:

const initialState = {
    isLoggedIn: false,
    currentAdmin: {
    },
};

Теперь я хотел бы создать ProtectedRoute, который будет перенаправлять меня на маршрут входа в систему, когда я не вошел в систему. Я хотел создать нечто подобное в компоненте входа в систему, который бы перенаправил меня на маршрут '/', если я ' m вошел в систему.

Но в обоих случаях мой prop isLoggedIn изначально имеет значение false и обновляется через несколько миллисекунд. Это мой код компонента Login, который не работал должным образом:

const Login = props => {

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => {
            setRedirect(props.isLoggedIn);

    }, [props.isLoggedIn]);

    return redirect ? <Redirect to={'/'} /> : (
    /* the login form code */
    )
}

Форма отображается на мгновение, и после этого я перенаправлен на основной маршрут. Как я могу предотвратить отображение формы? И как я могу сделать PrivateRoute в ожидании, чтобы получить все реквизиты и получить первоначальный статус isLoggedIn?

1 Ответ

0 голосов
/ 20 марта 2020

Не уверен, что я полностью понимаю контекст того, что вы делаете, но вот мои мысли. В вашем useEffect логическое значение isLoggedIn, по-видимому, управляет логическим значением перенаправления, которое может вызывать нежелательные побочные эффекты.

Попробуйте вместо этого

const Login = props => {

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => {
            // If user is not logged in, redirect them
            if (!props.isLoggedIn) {
            setRedirect(true)
     }

    }, [props.isLoggedIn]);

    return redirect ? <Redirect to={'/'} /> : (
    /* the login form code */
    )
}

Если вы используете реагирующий маршрутизатор, и вы экспортируете этот компонент с помощью withRouter компонента более высокого порядка, может быть лучше использовать history.push для того, что вы пытаетесь выполнить sh

const Login = props => {

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => {
            // If user is not logged in, redirect them
            if (!props.isLoggedIn) {
            props.history.push('/redirectRoute')
     }

    }, [props.isLoggedIn]);

    return redirect ? <Redirect to={'/'} /> : (
    /* the login form code */
    )
}
...