[英]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不在頁面加載時登錄用戶的過程中),我們會將用戶重定向到主頁。
注銷時:由於userDoc
和loggingIn
都是反應性數據源,因此loggingIn
這些變量之一發生更改,此autorun
功能都會重新運行。 因此,當用戶以任何方式注銷時, userDoc
將停止定義,條件將解析為true
,並將用戶重定向到主頁。
登錄時:如果注銷用戶登錄或開始登錄,則不會發生任何事情。 該函數將重新運行,但是userDoc
或loggingIn
變量更改可能變得更加復雜,就強制進行自動重定向。
老實說,我放棄了使用軟件包為帳戶系統創建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.