Meteor.user()和localStorage.getItem(' Meteor.userId')返回null

时间:2017-04-24 16:15:06

标签: javascript meteor

Meteor.user()localStorage.getItem('Meteor.userId')返回null,直到刷新页面 我正在使用来自Meteor.user()的值来尝试更改状态,从而重新呈现组件,但它会一直返回null直到页面重新加载。

export default class Header extends React.Component {
  constructor(props){
    super(props);
    this.state = {loggedIn: Meteor.user() !== null}// false if no user 
    //is logged in
    //save the component context to avoid scope issues
    thisComponent = this;
 }

 onSubmit(e){
    e.preventDefault();
    let el = $(e.target);
    let email = el.find('#email').val();
    let password = el.find('#password').val();
    let confirmPassword = el.find('#confirmPassword').val();

    // Login user
    Meteor.loginWithPassword(email, password, err => {
      if (err) {
        Materialize.toast(err.reason, 4000);
      } else {
        Materialize.toast('Success loging in', 4000);
        //change state just to cause a rerender
        thisComponent.setState({ loggedIn: true })
      }
    });
  }

  render() {
    //if user is logged in
    if(Meteor.user()) {
      return <Redirect to='/dashboard' />;
    } else {
      return <LoginComponent />;   
    }
  }

2 个答案:

答案 0 :(得分:1)

您需要使用反应式数据源来访问组件中的Meteor.user()对象。最好的方法是包装(整个应用程序)或仅将数据容器中的特定组件包装为将Meteor.user()对象作为道具传递给组件。

使用createContainer的示例:

import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Header } from '/imports/ui/components/Header';

export default createContainer(() => {
    const loading = !Meteor.user();
    const user = Meteor.user();
    return { loading, user };
}, Header);

然后在标题中:

export default class Header extends React.Component {
   constructor(props){
       super(props);
       this.state = { loggedIn: !!user}
       thisComponent = this;
   }

   onSubmit(e){
       e.preventDefault();
       let el = $(e.target);
       let email = el.find('#email').val();
       let password = el.find('#password').val();
       let confirmPassword = el.find('#confirmPassword').val();
       // Login user
       Meteor.loginWithPassword(email, password, err => {
           if(err){
               Materialize.toast(err.reason, 4000);
           }else {
               Materialize.toast('Success loging in', 4000);
              //change state just to cause a rerender
               thisComponent.setState({ loggedIn: true })
           }
      });
   }

  render() {
      { !!user ? <Redirect to='/dashboard' /> : <LoginComponent /> }
  }
}

答案 1 :(得分:0)

由于异步问题,Meteor.user()返回错误!

(Meteor.userId()只返回一个ID,它比Meteor.user()更快 - 返回一个对象)

因此,您可以使用Komposer来包装您的组件,这也是Meteor / React应用程序中的标准组件(并为页面提供足够的时间来加载Meteor.user()对象并将其作为道具传递到Header组件中):

创建 HeaderComposer 文件:

import React from 'react';
import {composeWithTracker} from 'react-komposer';
// also import your Header here..

function composer(props, onData) {
  const user = Meteor.user();
  onData(null, {user})
};

export default composeWithTracker(composer)(Header);

并在您的Header文件中:

export default class Header extends React.Component {
  constructor(props){
    super(props);
    this.state = {loggedIn: this.props.user !== null}// false if no user 
    //is logged in
    //save the component context to avoid scope issues
    thisComponent = this;
 }

 onSubmit(e){
    e.preventDefault();
    let el = $(e.target);
    let email = el.find('#email').val();
    let password = el.find('#password').val();
    let confirmPassword = el.find('#confirmPassword').val();

    // Login user
    Meteor.loginWithPassword(email, password, err => {
      if (err) {
        Materialize.toast(err.reason, 4000);
      } else {
        Materialize.toast('Success loging in', 4000);
        //change state just to cause a rerender
        thisComponent.setState({ loggedIn: true })
      }
    });
  }

  render() {
    //if user is logged in
    if(this.props.user) {
      return <Redirect to='/dashboard' />;
    } else {
      return <LoginComponent />;   
    }
  }
}

当然,在另一个组件文件中,您可以在其中呈现标题组件,可以随意使用 HeaderComposer