Meteor/React:重定向组件外部作为 AccountsTemplates.logout() 的回调

Meteor/React: Redirect outside of component as callback of AccountsTemplates.logout()

我正在尝试将 meteor-useraccounts 包与 React 集成到我的 Meteor 应用程序中。我已经走了很远,但我正在努力实现 history.push() 或等效的回调函数 AccountsTemplate.logout() - 后者是注销用户的内置方式。

回调函数的配置是这样完成的:

AccountsTemplates.configure({
    onLogoutHook: myLogoutFunc
})

但我无法在 React.Component 的 "class" 范围内执行此操作。所以我需要定义使用浏览器历史记录的回调函数,但我想它在任何组件范围之外。

对于点击符号In/Out按钮的情况,我找到解决方案如下:

class LogInOutButton extends Component {
    constructor(props) {
        super(props);

        this.state = {
            loggedIn: Meteor.userId() ? true : false,
            redirect: false
        }

        this.redirectToSignIn = this.redirectToSignIn.bind(this);

        window.logInOutButton = this;
    }

    redirectToSignIn() {
        if (!this.state.loggedIn && document.location.pathname !== "/signIn")
            this.setState({redirect: <Redirect to="/signIn" />});
    }

    render() {
        const { redirect } = this.state
        return (
            <li className="nav-item">
                {redirect}
                <a className="nav-link" href="#"
                    onClick={Meteor.userId() ? AccountsTemplates.logout : this.redirectToSignIn}>
                    {Meteor.userId() ? "Sign Out" : "Sign In"}
                </a>
            </li>
        )
    }
}

如您所见,例如,我尝试通过使 window 对象的成员从外部调用 redirectToSignIn() 方法。感觉不对也不行:

var myLogoutFunc = () =>
    window.logInOutButton.redirectToSignIn();

我也试过下面的方法:

var myLogoutFunc = withRouter(({history}) => 
    <div onLoad={history.push="/signIn"}>
    </div>
) 

但是,这行不通,因为 withRouter 需要一个组件作为参数,如果我做对了吗?至少这是我试图解释以下错误的方式:

Exception in delivering result of invoking 'logout': TypeError: "props is undefined"

withRouter 模块中阅读此内容后:

var withRouter = function withRouter(Component) {
  var C = function C(props) {
     ...

你会如何解决这个问题?

老实说,我放弃了使用包为帐户系统创建UI的想法。

meteor-useraccounts 是为 Blaze 制作的,尽管在官方的 Meteor 文档中他们鼓励包装呈现登录表单的 {{> atForm }} 模板,注册等进入 React.Component,我发现它会导致不兼容,尤其是在处理路由时。 (我曾使用包 gadicc:blaze-react-component 进行包装。) 最后我发现自己试图理解这个由多层组成的黑盒子,包括。另一个用于 bootstrap4 预样式。例如我也无法使电子邮件验证工作。

所以我决定放弃一切,开始在 Meteor Accounts and Meteor Passwords API.

之上构建整个 UI 和逻辑。

现在重定向非常简单,因为我可以在自己的 React.Component 中完成。您唯一需要做的就是 import { withRouter } from 'react-router';,然后 export default withRouter(LogInOutButton); 最后您可以使用 this.props.history.push("/signIn") 重定向:

import React, { Component } from 'react';
import { withRouter } from 'react-router';

class LogInOutButton extends Component {
    constructor(props) {
        super(props);

        this.state = {
            loggedIn: Meteor.userId() ? true : false,
        }

        this.redirectToSignIn = this.redirectToSignIn.bind(this);
    }

    redirectToSignIn() {
        if (this.state.loggedIn)
            Meteor.logout()
        if (document.location.pathname !== "/signIn")
            this.props.history.push("/signIn")
    }

    render() {
        return (
            <li className="nav-item">
                <a className="nav-link" href="#"
                    onClick={this.redirectToSignIn}>
                    {Meteor.userId() ? "Sign Out" : "Sign In"}
                </a>
            </li>
        )
    }
}

export default withRouter(LogInOutButton);

PS: (只是我的意见)当然,在构建自己的时候有一些事情需要解决UI/Logic 用于帐户系统。例如表单验证。 (我决定在 HTML5 验证的基础上构建,但使用 bootstrap4 添加我自己的视觉反馈。)

我想在 Meteor React 的情况下,目前根本没有工作包。我都试过了,相信我。它们都让人头疼(当试图将它们与 React 集成时)或不够可定制。如果我从一开始就花时间构建自己的,那么我现在早就完成了。自己动手的好处在于,您知道它是如何工作的,并且以后可以轻松地改进和重用它。

它还有助于保持较低的依赖性,我认为这很重要,因为 Meteor 项目在过去几年中一直在快速发展和变化。当您知道自己做了什么时,可以更轻松地使您的项目保持最新状态。

您是否只是试图在用户注销、已注销或未登录时进入 app/site 时将用户重定向到登录页面?我经常根据 app/routes/permissions/etc.

的复杂性以几种不同的方式进行此操作

我倾向于使用 iron:router 和 Blaze,而不是 React,但我认为最直接的解决方案是易于翻译。我将其放在客户端代码顶层的某处:

Tracker.autorun(function() {
    const userDoc = Meteor.user();
    const loggingIn = Meteor.loggingIn();

    if(!userDoc && !loggingIn) {
        Router.go('/'); // Or comparable redirect command
    }
});

页面加载时: 如果 userDoc 未定义(意味着用户未成功登录)并且 loggingIn 不为真(意味着 Meteor 未在页面加载时让用户登录),我们将将用户重定向到主页。

注销时: 由于 userDocloggingIn 都是反应性数据源,因此只要这些变量中的任何一个发生变化,这个 autorun 函数就会重新 运行 。因此,当用户以任何方式注销时,userDoc 将不再定义,条件将解析为 true 并将用户重定向到主页。

登录时: 如果注销的用户登录或开始登录,则不会发生任何事情。该函数将重新 运行,但在 userDocloggingIn 变量更改时强制自动重定向会变得更加复杂。