2016-05-28 194 views
2

當我註冊時,我被重定向到具有Navbar組件的/儀表板頁面。它與ReactMeteorDataWrap.jsx中定義的ReactMeteorData鏈接。註冊後,我在控制檯上獲得Object {_id:「qW8wQcc2sjiM8TXcc」,profile:Object,emails:Array [1]} data Object {currentUser:Object}。然而currentUser顯示爲空。currentUser顯示爲undefined

我的代碼

ReactMeteorDataWrap.jsx

const ReactMeteorDataWrap = (BaseComponent)=>{ 
    return class ExportClass extends Component { 
     getMeteorData(){ 
      let data = {}; 
      console.log(Meteor.user()); 
      data.currentUser = Meteor.user(); 
      console.log('data',data); 
      return data; 
     } 
     render(){ 
      return <BaseComponent getMeteor={()=>this.getMeteorData()} 
       {...this.props}></BaseComponent> 
     } 
    } 
} 

export default ReactMeteorDataWrap; 

Navbar.jsx(/儀表板)

import ReactMeteorDataWrap from '../ReactMeteorDataWrap.jsx'; 

    class Navbar extends Component { 
     constructor(props){ 
      super(props); 
      this.state = { searchText: '' }; 
      this.props.getMeteor(); //accessed from ReactMeteorDataWrap 
     } 

     componentDidMount(){ 
      const users = Meteor.users.find({},{fields:{'profile':1}}).fetch(); 
      const usernames = []; 
      users.map(function(user){ 
       usernames.push(user.profile.fullname); 
      }); 
      $('#typeahead').typeahead({ 
       name: 'users', 
       local: usernames 
      }); 
     } 

     handleSubmit(e){ 
      e.preventDefault(); 
      FlowRouter.go('/user/' + (this.refs.searchText.value).trim()); 
     } 

     render() { 
      let fullname = ''; 
      let currentUser = this.props.currentUser; 
      console.log('currentUser',this.props.currentUser); // returns undefined 
      if(currentUser && currentUser.profile){ 
       console.log('currentUser',currentUser); 
       fullname = currentUser.profile.firstname + ' ' + currentUser.profile.lastname; 
      } 
      console.log('fullname',fullname); // returns null 
      return (
         <div className="navbar navbar-blue navbar-fixed-top"> 
          <div className="navbar-header"> 
           <a href="/dashboard" className="navbar-brand logo"><i className="fa fa-facebook"></i></a> 
          </div> 
          <nav className="collapse navbar-collapse" role="navigation"> 
           <ul className="nav navbar-nav"> 
            <li> 
             <a href="/dashboard"><i className="fa fa-home"></i> News Feed</a> 
            </li> 
           </ul> 
           <ul className="nav navbar-nav navbar-right"> 
            <li className="dropdown"> 
             <a href="#" className="dropdown-toggle" data-toggle="dropdown"><i className="glyphicon glyphicon-user"></i> {fullname}</a> 
             <ul className="dropdown-menu"> 
              <li><a href="/profile">Edit Profile</a></li> 
              <li><a href="/signout">Logout</a></li> 
             </ul> 
            </li> 
           </ul> 
          </nav> 
         </div> 
      ); 
     } 
    } 
    export default ReactMeteorDataWrap(Navbar); 

SignupForm.jsx(後註冊用戶會被重定向到dashb OARD網頁,其中有上面導航欄)

import ReactMeteorDataWrap from '../ReactMeteorDataWrap.jsx'; 

class SignupForm extends Component { 
    constructor(props){ 
     super(props); 
     this.state = { 
      message:'', 
      messageClass:'' 
     } 
     this.handleSubmit = this.handleSubmit.bind(this); 
     this.props.getMeteor(); 
    } 

    displayError(message){ 
     console.log(message); 
     this.setState({ 
      message:message, 
      messageClass:'alert alert-danger registerError' 
     }); 
    } 

    handleSubmit(e){ 
     e.preventDefault(); 
     this.setState({message:'', messageClass:'hidden'}); 
     const first_name = ReactDOM.findDOMNode(this.refs.first_name).value.trim(); 
     const last_name = ReactDOM.findDOMNode(this.refs.last_name).value.trim(); 
     const email = ReactDOM.findDOMNode(this.refs.email).value.trim(); 
     const password = ReactDOM.findDOMNode(this.refs.password).value.trim(); 
     const user = { 
      email:email,password:password, 
      profile:{ 
       fullname:(first_name + last_name).toLowerCase(), 
       firstname:first_name, lastname:last_name, 
       avatar:'http://placehold.it/150*150', 
       friends:[] 
      } 
     } 
     Accounts.createUser(user,(e) => { 
      console.log('user',user); 
      console.log('e',e); 
      if (e) { 
       this.displayError(e.reason); 
      } else { 
       FlowRouter.go('/dashboard'); 
      } 
     }); 
    } 

    render() { 
     return (
      <div className="row"> 
       <div className="signup"> 
        <h1>Sign up</h1> 
        <p className="text-muted">It's free and will always be</p> 
       </div> 
       <form onSubmit={this.handleSubmit}> 
        <div className="col-sm-9"> 
         <div className="row"> 
          <div className="col-sm-6 form-group"> 
           <input type="text" name="first_name" placeholder="First Name" ref="first_name" className="form-control"/> 
          </div> 

          <div className="col-sm-6 form-group"> 
           <input type="text" name="last_name" placeholder="Last Name" ref="last_name" className="form-control"/> 
          </div> 
         </div> 

         <div className="form-group"> 
          <input type="text" name="email" placeholder="Email or mobile number" ref="email" className="form-control"/> 
         </div> 

         <div className="form-group"> 
          <input type="password" name="password" placeholder="Password" ref="password" className="form-control"/> 
         </div> 
         <button type="submit" className="btn btn-md btn-success">signup</button> 
         <span className={this.state.messageClass}>{this.state.message}</span> 
        </div> 
       </form> 
      </div> 
     ); 
    } 
} 
export default ReactMeteorDataWrap(SignupForm); 

是通過兩個SignupForm和Navbar.jsx道具調用getMeteorData()好嗎?因爲我想以es6的方式使用mixins功能。

+0

代替this.props.currentUser你做this.props.getMeteor()currentUser,它會工作。 – Tushant

+0

我會查看[react-komposer](https://github.com/kadirahq/react-komposer)中的反應性高階組件實現。 – MasterAM

回答

1

當您登錄和您重定向到/儀表板,兩件事情發生在一次:

  1. 陣營呈現新組件
  2. 流星開始到Meteor.users集合同步。

無法保證Meteor.user()在React開始渲染時可用。事實上,當React組件掛載時,用戶仍然很有可能是未定義的。

當您的ReactMeteorDataWrap.render調用getMeteorData時,用戶仍然未定義,這就是您所看到的。問題在於當用戶文檔更新時,您的代碼不會再次調用getMeteorData

有幾種方法可以解決這個問題。我建議使用createContainer形式的react-meteor-data包,它類似於你的ReactMeteorDataWrap類,除了它實際上有效。 :)

這裏有一個修復,使得this.props.userNavBar可用:

export default createContainer(() => { 
    return { user: Meteor.user() }; 
}, NavBar); 
+0

是的,你是正確的,當我註冊,我重定向到儀表板頁面,然後顯示用戶名,但如果我刷新儀表板頁面我的用戶名爲未定義。 – milan

+0

我對這些mixin有問題。我的儀表板頁面只需要用戶名,所以有ReactMeteorDataWrap,我也需要使用這個ReactMeteorDataWrap for statusForm,而不是隻有用戶名,我需要獲取該用戶的所有帖子。 – milan