currentUser显示为undefined

当我注册时,我被redirect到具有Navbar组件的/仪表板页面。 它与ReactMeteorDataWrap.jsx中定义的ReactMeteorData链接。 注册后,我在控制台上得到Object {_id:“qW8wQcc2sjiM8TXcc”,profile:Object,emails:Array [1]} data Object {currentUser:Object}。 但是currentUser显示为空。

我的代码

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(注册后用户将被redirect到仪表盘页面上方有导航栏)

 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的方式使用mixinsfunction。

当你login,你被redirect到/仪表板,两件事情一次发生:

  1. React呈现新的组件
  2. meteor开始同步Meteor.users集合。

不能保证Meteor.user()在React开始渲染的时候可用。 事实上,当React组件挂载时,用户仍然很有可能是未定义的。

当你的ReactMeteorDataWrap.render调用getMeteorData ,用户仍然是未定义的,这就是你所看到的。 问题是当用户文档更新时,你的代码不会再次调用getMeteorData

有几种方法可以解决这个问题。 我build议使用createContainerforms的react-meteor-data包,它与ReactMeteorDataWrap类相似,只是它实际上起作用。 🙂

这里有一个修复,使得在NavBar可以使用this.props.user

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