2016-05-28 137 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