Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Meteor/React:将组件外部重定向为AccountsTemplates.logout()的回调_Javascript_Reactjs_Meteor_Browser History_Meteor Useraccounts - Fatal编程技术网

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

Javascript Meteor/React:将组件外部重定向为AccountsTemplates.logout()的回调,javascript,reactjs,meteor,browser-history,meteor-useraccounts,Javascript,Reactjs,Meteor,Browser History,Meteor Useraccounts,我正在尝试在我的meteor应用程序中将meteor useraccounts与React集成。我已经走了相当远的路,但我正在努力实现一个历史记录.push()或等效函数,作为AccountsTemplate.logout()的回调函数,后者是用户注销的内置方式 回调函数的配置是通过以下方式完成的: AccountsTemplates.configure({ onLogoutHook: myLogoutFunc }) 但我不能在React.Component的“类”中完成这项工作。所以

我正在尝试在我的meteor应用程序中将meteor useraccounts与React集成。我已经走了相当远的路,但我正在努力实现一个
历史记录.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>
        )
    }
}
我还尝试了以下方法:

var myLogoutFunc = withRouter(({history}) => 
    <div onLoad={history.push="/signIn"}>
    </div>
) 
在使用路由器阅读
模块后:

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

您将如何解决这个问题?

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

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

所以我决定放弃它,开始在Meteor和Meteor上构建整个UI和逻辑

现在重定向非常简单,因为我可以在自己的React.Component中完成。你唯一需要做的就是从“react router”导入{withRouter}
,然后
使用路由器导出默认值(LogInOutButton)最后,您可以使用
this.props.history.push(“/sign”)
重定向:

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);
import React,{Component}来自'React';
从“react router”导入{withRouter};
类LogInOutButton扩展组件{
建造师(道具){
超级(道具);
此.state={
loggedIn:Meteor.userId()?true:false,
}
this.redirectToSignIn=this.redirectToSignIn.bind(this);
}
重定向到信号素(){
if(this.state.loggedIn)
Meteor.logout()
if(document.location.pathname!==“/sign”)
this.props.history.push(“/sign”)
}
render(){
返回(
  • ) } } 使用路由器导出默认值(LogInOutButton);

    PS:(只是我的意见)当然,在为帐户系统构建自己的UI/逻辑时,需要解决一些问题。例如表单验证。(我决定建立在HTML5验证的基础上,但添加了我自己的视觉反馈。)

    我想在Meteor和React的案例中,目前根本没有工作包。我都试过了,相信我。它们都是令人讨厌的东西(当试图将它们与React集成时),或者是不够可定制。如果我从一开始就花时间建造自己的,我早就完成了。自己动手做的好处是,您知道它是如何工作的,并且可以很容易地在以后对其进行改进和重用


    它也有助于保持低依赖性,这一点我认为至关重要,因为Meteor项目在过去几年中一直在快速发展和变化。当你知道你做了什么时,让你的项目保持最新就更容易了。

    你只是想在用户注销、注销或未登录时将用户重定向到登录页吗?根据我的应用程序/路由/权限等的复杂程度,我通常会采用几种不同的方法来实现这一点

    我倾向于使用熨斗:路由器和火焰,而不是反应,但我认为最直接的解决方案很容易翻译。我把它放在客户端代码的顶层:

    Tracker.autorun(function() {
        const userDoc = Meteor.user();
        const loggingIn = Meteor.loggingIn();
    
        if(!userDoc && !loggingIn) {
            Router.go('/'); // Or comparable redirect command
        }
    });
    
    页面加载时: 如果未定义
    userDoc
    (表示用户未成功登录)且
    logginging
    不正确(表示Meteor未在页面加载时登录用户),我们将用户重定向到主页

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

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

    那么您想在用户注销后将用户重定向到登录页面吗?为什么不使用
    Meteor.logout()
    然后使用
    props.history
    重定向?是的,这就是我想要做的。meteor useraccounts包的作者建议改为使用AccountsTemplates.logout()。如果你告诉我,这是安全的,那将是一个选项。以前永远不要使用meteor useraccounts,如果你完全使用他们的模板来呈现注销/登录按钮,那么你应该使用
    AccountsTemplates.logout()
    。meteor.logout()是相当安全的believe@Mikkel是的,但是有问题。这些文档已经过时了,我没有找到一种方法让它与React Router v4一起工作,这是完全不同的。你成功了吗?不久前,我最初是出于自己的目的对其进行黑客攻击的,但我注意到其中一位开发人员将其用于支持像你这样的定制解决方案:)这是如此简单和直接,但我被困在了我的脑海中
    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);
    
    Tracker.autorun(function() {
        const userDoc = Meteor.user();
        const loggingIn = Meteor.loggingIn();
    
        if(!userDoc && !loggingIn) {
            Router.go('/'); // Or comparable redirect command
        }
    });