React-Redux如何在重定向之前防止页面呈现

Jus*_*tin 5 reactjs react-router redux react-redux

我正在处理一个个人项目,无法检查用户是否已登录,因此当他们尝试转到/ login时,它将把他们重定向到主页。目前,我的代码执行以下操作:

  1. 定义了我自己的路线组件
  2. 调用checkIfSignedIn时,它将分派将isLoggedIn状态设置为True或False的操作。
  3. AuthenticatedRouter组件检查商店的isLoggedIn状态是true还是false,并将呈现该组件或重定向到主页。
  4. 此方法有效,但是问题在于isLoggedIn最初为false,因此如果登录,则登录表单会显示一秒钟,然后在isLoggedIn变为true后重定向。

我无法弄清楚如何使用默认状态渲染组件,然后由于状态更改而突然重定向,从而解决该问题。谢谢

  • 我正在为用户帐户使用Firebase。

Routes.js

const Routes = (props) => {
    props.checkIfSignedIn();
    return(
        <Router>
            <Switch>
                <Route exact path='/' component={App}/>
                <AuthorizedRoute path="/signup" component={SignUp}/>
                <AuthorizedRoute path="/signin" component={SignIn}/>
                <Route component={InvalidPage}/>
            </Switch>
        </Router>
    );
};

const mapDispatchToProps = (dispatch) => {
    return{
        checkIfSignedIn: () => dispatch(checkIfSignedIn())
    };
};

export default connect(null, mapDispatchToProps)(Routes);
Run Code Online (Sandbox Code Playgroud)

AuthorizedRoute.js

class AuthorizedRoute extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            isLoggedIn: false
        };
    };

    render(){
        const { component: Component, ...rest } = this.props;
        return(
            <Route {...rest} render={props => {
                if (this.props.isLoggedIn){
                    console.log(this.state.isLoggedIn);
                    return <Redirect to="/" />
                } else{
                    return <Component {...props} />
                }
            }} />
        );
    }
};


const mapStateToProps = (state) => {
    return{
        isLoggedIn : state.authentication.isLoggedIn
    };
};

export default connect(mapStateToProps, null)(AuthorizedRoute);
Run Code Online (Sandbox Code Playgroud)

authentication.js-动作创建者

const setSignedInFalse = () => {
    return{
        type: IS_SIGNED_IN_FALSE
    };
};

const setSignedInTrue = () => {
    return{
        type: IS_SIGNED_IN_TRUE
    };
};

const checkIfSignedIn = () => {
    return dispatch => {
        firebaseApp.auth().onAuthStateChanged(user => {
            if (user){
                dispatch(setSignedInTrue());
            } else{
                dispatch(setSignedInFalse());
            }
        });
    };
};

export default checkIfSignedIn;
Run Code Online (Sandbox Code Playgroud)

authentication.js-精简器

const defaultState = {
    isLoggedIn: false
};

const authentication = (state = defaultState, action) => {
    let authenticationState = null;
    switch (action.type){
        case IS_SIGNED_IN_FALSE:
            authenticationState = {
                isLoggedIn: false
            };
            return authenticationState;
        case IS_SIGNED_IN_TRUE:
            authenticationState = {
                isLoggedIn: true
            };
            return authenticationState;
        default:
            return state;
    };
};

export default authentication;
Run Code Online (Sandbox Code Playgroud)

Hacky解决方案(不确定是否对此感到不满意)。

我将Auth reducer的默认状态设置为isLoggedIn:null而不是false。然后,在我的AuthorizedRoute组件中,我现在具有3个条件以首先呈现null,然后呈现该组件或重定向。

//AuthorizedRoute Component
if (this.props.isLoggedIn){
    return <Redirect to="/" />
} else if (this.props.isLoggedIn === false){
    return <Component {...props} />
} else{
    return null;
}
Run Code Online (Sandbox Code Playgroud)

Fab*_*ard 2

你可以做的是这样的:(在你的 auth reducer 中)。

let user = JSON.parse(localStorage.getItem('user'));
const initialState = user ? { isLoggedIn: true } : {};
Run Code Online (Sandbox Code Playgroud)

此外,您还必须在用户登录时设置本地存储,并在用户注销时将其删除。