0

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

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

AccountsTemplates.configure({
    onLogoutHook: myLogoutFunc
})

但我不能在 React.Component 的“类”中做到这一点。所以我需要定义使用浏览器历史记录的回调函数,但我猜它不在任何组件范围内。

对于点击登录/退出 按钮的情况,我找到了如下解决方案:

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>
        )
    }
}

如您所见,例如,我尝试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) {
     ...

你会如何解决这个问题?

4

2 回答 2

1

您是否只是在用户注销、注销或未登录时进入应用程序/站点时尝试将用户重定向到登录页面?根据我的应用程序/路由/权限/等的复杂性,我经常以几种不同的方式执行此操作。

我倾向于使用 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变量更改可能变得更加复杂时强制执行自动重定向。

于 2018-12-30T20:47:34.920 回答
0

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

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

所以我决定放弃这一切,并开始自己在 Meteor Accounts和 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添加我自己的视觉反馈。)

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

它还有助于保持较低的依赖关系,我认为这很重要,因为 Meteor 项目在过去几年中一直在迅速发展和变化。当您知道自己做了什么时,更容易让您的项目保持最新。

于 2018-12-30T09:30:36.357 回答