2017-04-07 89 views
0

我正在開發React + Meteor應用程序,並且遇到用戶登錄功能問題。當流星用戶登錄時,React不會更改爲LoggedInView

我有一個基於用戶是否已登錄顯示不同的組件頭導航欄

這樣的:

export default class Header extends Component { 
    constructor(props) { 
     super(props) 

     this.state = { 
      user: Meteor.user() 
     } 
    } 

    render() { 
     return (
      <header className="main-header"> 
       <nav className="navbar navbar-static-top"> 
        <div className="navbar-custom-menu"> 
         {this.state.user() !== null ? <LoggedInNavigation /> : <LoggedOutNavigation />} 
        </div> 
       </nav> 
      </header> 
     ) 
    } 
} 

現在這個工作,但它並沒有在改變用戶正在登錄。我必須刷新頁面才能更改視圖(顯然這並不理想)。

這裏是我的登錄代碼:

Meteor.loginWithPassword(this.state.email, this.state.password, (error) => { 
    if (error) 
     this.setState({ meteorError: "Error: " + error.reason }) 
    else { 
     this.setState({ meteorError: "" }) 
     // Handle successful login 
    } 
}) 

的問題是這些代碼兩個街區坐在不同的組件。

第一個塊位於imports/ui/components/main-layout/Header,第二個塊位於imports/ui/components/authentication/Login

正如我所說的,問題是用戶可以登錄,但視圖不會根據身份驗證狀態而改變。解決這個問題的最佳做法是什麼?

編輯:

這裏是組件的層次結構:

1 - LoggedOutNav

MainLayout -> Header -> LoggedOutNav 

2 - 這裏登錄代碼

MainLayout -> Routes -> (Route path="/login" component={Login}) -> LoginForm 
+0

這是行不通的,因爲國家有爲了改變是否重新渲染... –

+0

的觀點不會改變,因爲渲染**會被調用只有在使用this.setState **(並且您在登錄成功時未在Header中調用setState)或者提供給Component的道具更改時纔會發生。爲了找到你的特定案例的一個很好的解決方案,你應該告訴我們這些組件(親子,另一個組件的孩子......)之間的關係。 –

+0

我會更新我的問題(有一個很遠的距離關係) –

回答

1

的問題是,你的類的構造函數將只運行只要組件被安裝,就永遠不會再一次。所以即使Meteor.user()會改變,你的state不會。當a)props更改或b)您的state發生變化時,該組件將重新提交,例如,當你撥打setState。我們可以利用a)通過流星createContainer HOC(react-meteor-data)來包裝您的Header類,併爲其設置一個被動數據上下文。當數據發生變化時,Header的道具將會更改,並且組件會重新顯示。在代碼,將是這樣的:

import { Meteor } from 'meteor/meteor'; 
import { createContainer } from 'meteor/react-meteor-data'; 
import React, { Component, PropTypes } from 'react'; 

class HeaderComponent extends Component { 
    render() { 
     const { user } = this.props; 
     return (
      <header className="main-header"> 
       <nav className="navbar navbar-static-top"> 
        <div className="navbar-custom-menu"> 
         {user ? <LoggedInNavigation /> : <LoggedOutNavigation />} 
        </div> 
       </nav> 
      </header> 
     ) 
    } 
} 

export const Header = createContainer(() => { 
    // assuming you have a user publication of that name... 
    Meteor.subscribe('users/personalData'); 
    return { 
     user: Meteor.user(), 
    }; 
}, HeaderComponent); 
+0

Omw老兄,非常感謝你! –

+0

沒問題,很高興我能幫上忙。 – tomsp