【问题标题】:How can I redirect before render?如何在渲染之前重定向?
【发布时间】:2019-07-03 10:27:36
【问题描述】:

我正在尝试使用 react 构建一个网络应用程序,但我有点碰壁了。

问题是,我不希望任何已经登录的用户访问登录页面。

我尝试使用render方法和componentDidMount方法重定向它们,但是由于在componentDidMount之前调用了render方法,所以在重定向之前登录页面会闪烁。

这些是我的代码。

我正在使用 redux 和 firebase 来控制组件状态并进行身份验证。

class CenterPanel extends Component {
    render() {
        const { user }=this.props;

        if(user!=null) { //this is how I tried to redirect
            return ( //
                <Redirect to='/somewhereNotHere' />
            );
        }

        return ( //this flashes out before redirection
            <div className={cx('center_panel')}>
                <div className={cx('button')}>
                    login
                </div>
            </div>
        );
    }

    componentDidMount() {
        const { changeUserStatus }=this.props;

        firebase.auth().onAuthStateChanged(
            (user) => changeUserStatus(user)
        );
    }
}

不胜感激任何建议。 提前谢谢。

【问题讨论】:

  • 尝试将 window.location 设置为 '/somewhereNotHere'
  • 我试过 window.location 和 history。两者都重定向成功,但是重定向前登录页面仍然闪现。我希望已经登录的用户完全无法访问登录页面。
  • 当用户不为空时只返回null 而不是&lt;div ... /&gt; 树。但是在返回 null 之前重定向...
  • 你从哪里得到user 道具值?

标签: reactjs


【解决方案1】:

也许在你调用onAuthStateChanged之前,道具user是未定义的

如果正确,您可以通过三个user 值来控制您的组件。未定义,null,用户值。

render() {
        const { user }=this.props;

        if(user === undefined){
            return null; //or Loading component
        }

        if(user!=null) { //this is how I tried to redirect
            return ( //
                <Redirect to='/somewhereNotHere' />
            );
        }

        return ( //this flashes out before redirection
            <div className={cx('center_panel')}>
                <div className={cx('button')}>
                    login
                </div>
            </div>
        );
    }

【讨论】:

  • 谢谢!解决了问题!将用户状态划分为 undefined、null、用户 obj 的想法非常有效。
  • 快速说明:在 react-router-dom 6v Redirect 被 Navigate 取代后。
【解决方案2】:

你应该试试这个,

if(user && user!==null) { //this is how I tried to redirect
     return <Redirect to='/somewhereNotHere' />  //Make sure you have imported Redirect from correct package i.e. react-router-dom
}else{
     return ( //this flashes out before redirection
            <div className={cx('center_panel')}>
                <div className={cx('button')}>
                    login
                </div>
            </div>
     );
}

Another way 这样做是在Routes 本身,

<Route exact path="/your_Path_to_component" render={() => (
  user ? ( //get the user data as you are passing as props to CenterPanel component
    <Redirect to="/somewhereNotHere"/>
  ) : (
    <CenterPanel />
  )
)}/>

这样就不需要将user作为props传递给CenterPanel组件,也不需要在CenterPanel组件中编写任何重定向逻辑。

【讨论】:

  • 来晚了,把它放在路由器中可能会被视为违反封装原则,好像将来您将在主索引文件中渲染路由器之前添加更复杂的验证,并且组件将被耦合。另一方面,render 方法中的组件负责重定向的整个反应概念违背了许多其他 OOP 原则。在我看来,您展示的第一种方法更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2021-07-20
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多