簡體   English   中英

流星/反應:重定向到組件外部作為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的“類”中執行此操作。 因此,我想我需要定義使用瀏覽器歷史記錄的回調函數,但它不在任何Components范圍內。

對於單擊“ 登錄/注銷” 按鈕的情況 ,我發現了以下解決方案:

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需要一個Component作為參數,如果我理解正確的話? 至少這是我嘗試解釋以下錯誤的方法:

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

withRouter模塊中閱讀以下內容后:

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

您將如何解決?

您是在嘗試注銷用戶,注銷用戶還是未登錄到應用程序/站點時將用戶重定向到登錄頁面嗎? 我經常根據我的應用程序/路由/權限/等的復雜性以幾種不同的方式執行此操作。

我傾向於使用鐵:路由器和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都是反應性數據源,因此loggingIn這些變量之一發生更改,此autorun功能都會重新運行。 因此,當用戶以任何方式注銷時, userDoc將停止定義,條件將解析為true ,並將用戶重定向到主頁。

登錄時:如果注銷用戶登錄或開始登錄,則不會發生任何事情。 該函數將重新運行,但是userDocloggingIn變量更改可能變得更加復雜,就強制進行自動重定向。

老實說,我放棄了使用軟件包為帳戶系統創建UI的想法。

軟件包meteor-useraccounts是為Blaze制作的,盡管在官方Meteor文檔中,他們鼓勵將{{> atForm }}模板包裝起來,以將Sign In,Sign Up等表單呈現為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 /邏輯時,當然要解決一些問題。 例如表單驗證。 (我決定在HTML5驗證的基礎上構建,但是使用bootstrap4添加了自己的視覺反饋。)

我想在Meteor React的情況下,目前根本沒有任何工作包。 我全部嘗試了,相信我。 當他們試圖將它們與React集成在一起時,它們都是痛苦的,或者定制得不夠。 如果我從一開始就花時間構建自己的產品,那么現在我早已完成。 自己做的最大好處是,您知道它是如何工作的,以后可以輕松地對其進行完善和重用。

這也有助於保持較低的依賴關系,這是至關重要的,因為在過去的幾年中,Meteor項目一直在快速發展和變化。 當您知道自己做了什么時,更容易使項目保持最新狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM