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

IT技术 reactjs redux react-router react-redux
2021-05-22 14:06:06

我正在处理一个个人项目,但在检查用户是否登录时遇到问题,因此当他们尝试转到 /login 时,它会将他们重定向到主页。目前我的代码的作用如下:

  1. 定义我自己的路由组件
  2. 调用 checkIfSignedIn 时,它会调度将 isLoggedIn 状态设置为 True 或 False 的操作。
  3. AuthenticatedRouter 组件会检查商店的 isLoggedIn 状态是真还是假,并且将呈现组件或重定向到主页。
  4. 这是有效的,但问题是 isLoggedIn 最初是假的,所以如果他们已登录,登录表单会显示一秒钟,然后在 isLoggedIn 变为真后重定向。

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

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

路由.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);

授权路由.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);

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;

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;

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;
}
2个回答

你可以做的是这样的:(在你的身份验证减速器中)。

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

此外,您必须在用户登录时设置 localstorage,并在他注销时将其删除。

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

    render() {
        const { component: Component, ...rest } = this.props;
        const user = JSON.parse(localStorage.getItem('user'));
        return (
            <Route { ...rest } render={ props => user ? <Component {...props} /> : <App /> } />
        );
    }
};


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

export default connect(mapStateToProps, null)(AuthorizedRoute);