currentUser显示为未定义 [英] currentUser is displayed undefined

查看:72
本文介绍了currentUser显示为未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注册后,我将重定向到具有Navbar组件的/dashboard页面.它与ReactMeteorDataWrap.jsx中定义的ReactMeteorData链接.注册后,我在控制台上获得对象{_id:"qW8wQcc2sjiM8TXcc",配置文件:对象,电子邮件:Array [1]}数据对象{currentUser:Object}.但是currentUser显示为空.

When i signup, I am redirected to /dashboard page which has Navbar component. It is linked with ReactMeteorData that is defined in ReactMeteorDataWrap.jsx. After signing up, i get Object {_id: "qW8wQcc2sjiM8TXcc", profile: Object, emails: Array[1]} data Object {currentUser: Object} on console. However currentUser is displayed null.

我的代码

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(/dashboard)

 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(注册后,用户将被重定向到上面具有导航栏的仪表板页面)

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功能.

Is calling getMeteorData() through props in both SignupForm and Navbar.jsx ok? Because i wanted to use mixins functionality in es6 way.

推荐答案

登录并重定向到/dashboard时,会同时发生两件事:

When you log in and you're redirected to /dashboard, two things happen at once:

  1. React渲染新组件
  2. 流星开始同步Meteor.users集合.
  1. React renders the new components
  2. Meteor starts to synchronize the Meteor.users collection.

无法保证React开始渲染时Meteor.user()可用.实际上,在安装React组件时很有可能用户仍未定义.

There's no guarantee that Meteor.user() is available by the time React starts rendering. In fact it's very probable that the user is still undefined when the React component mounts.

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

When your ReactMeteorDataWrap.render calls getMeteorData, the user still is undefined, that's what you see. The problem is that your code doesn't call getMeteorData again when the user document is updated.

有几种方法可以解决此问题.我建议使用createContainer形式的 react-meteor-data 包与ReactMeteorDataWrap类类似,不同之处在于它实际上可以工作. :)

There are several ways you can fix this. I'd recommend using createContainer form the react-meteor-data package, which is similar to your ReactMeteorDataWrap class, except that it actually works. :)

这是使this.props.userNavBar中可用的修复程序:

Here's a fix that makes this.props.user be available in NavBar:

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

这篇关于currentUser显示为未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆