我正在苦苦思索如何在react组件中等待Meteor.user()订阅。我知道用户是登录的,因为Meteor.userId()返回了_id,但尝试访问电子邮件地址时显示Meteor.user()返回了undefined。我猜是因为它现在还不能使用。
可惜,由于Meteor.user()不是我手动订阅的发布,我不确定如何在React组件中等待它。谁能给我举个例子?
import { Meteor } from 'meteor/meteor';
import React from 'react';
import { Link } from 'react-router';
import { createContainer } from 'meteor/react-meteor-data';
import './BaseLayout.scss';
class BaseLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
isAuthenticated: (Meteor.userId() !== null) ? true : false,
}
}
componentWillMount() {
if (!this.state.isAuthenticated) {
this.context.router.push('/login');
}
}
componentDidUpdate(prevProps, prevState) {
if (!this.state.isAuthenticated) {
this.context.router.push('/login');
}
}
toggleUserMenu() {
this.refs.userMenu.style.display = (this.refs.userMenu.style.display === 'block') ? 'none' : 'block';
}
logout(e) {
e.preventDefault();
Meteor.logout();
this.context.router.push('/login');
}
render() {
return(
<div id="base">
<div id="header">
<div id="top-bar" className="clear-fix">
<div className="float-left" id="logo"></div>
<div className="float-right" id="user-menu">
<div onClick={this.toggleUserMenu.bind(this)}>
<span>{this.props.currentUser.emails[0].address}</span>
<div className="arrow-down"></div>
</div>
<div id="user-menu-content" ref="userMenu">
<a onClick={this.logout.bind(this)}>Sign Out</a>
</div>
</div>
</div>
</div>
<div id="bodyContainer">
{this.props.children}
</div>
<div id="footer">
<ul>
<li><a href="mailto:test@example.com">Made by Us</a></li>
</ul>
</div>
</div>
)
}
}
BaseLayout.contextTypes = {
router: React.PropTypes.object.isRequired,
}
export default BaseLayoutContainer = createContainer(() => {
var handle = Meteor.subscribe("user.classrooms");
return {
currentUser: Meteor.user(),
dataLoading: !handle.ready(),
classrooms: Classrooms.find({}).fetch(),
};
}, BaseLayout);发布于 2016-09-19 01:18:31
你可以使用一个三元运算
currentUser ? true : flase此外,保持组件有序的一个很好的技巧是始终使用destructure,例如,您可以使用const { currentUser } = this.props;而不是const currentUser = this.props.currentUser来查看:
render() {
const { currentUser, children } = this.props;
return (
<div id="base">
<div id="header">
<div id="top-bar" className="clear-fix">
<div className="float-left" id="logo"></div>
<div className="float-right" id="user-menu">
<div onClick={this.toggleUserMenu.bind(this)}>
{currentUser ?
<span>{currentUser.emails[0].address}</span> :
<span>Loading...</span>
}
<div className="arrow-down"></div>
</div>
<div id="user-menu-content" ref="userMenu">
<a onClick={this.logout.bind(this)}>Sign Out</a>
</div>
</div>
</div>
</div>
<div id="bodyContainer">
{children}
</div>
<div id="footer">
<ul>
<li><a href="mailto:test@example.com">Made by Us</a></li>
</ul>
</div>
</div>
)
}发布于 2017-10-04 13:23:12
被接受的答案是好的,但是过了一段时间,你会注意到你将不得不在许多组件上重复很多次。或者,您可以在使用Tracker呈现顶级组件之前侦听以确保Accounts.loginServicesConfigured()为真。引用meteor文档:“Accounts.loginServicesConfigured()函数是一个反应式数据源,一旦配置了登录服务,它将返回true”。我正在使用meteor、react、redux和react路由器。
import React, { Component } from 'react';
import { Accounts } from 'meteor/accounts-base';
import { Route, Switch } from 'react-router-dom';
import { Tracker } from 'meteor/tracker';
class App extends Component {
constructor(props) {
super(props);
this.state = { loading: true };
}
componentWillMount() {
Tracker.autorun(() => {
if (Accounts.loginServicesConfigured()) {
this.setState({ loading: false });
}
});
}
render() {
return (
<div className="app">
{
this.state.loading ? (<Spinner />) : (
<Route exact path="/" component={HomePage} />
)
}
</div>
);
}
}希望这个替代方案能帮助其他人。祝你好运!
发布于 2017-05-05 05:47:37
将dataLoading:!handle.ready() || !Meteor.user()添加到createContainer。
export default BaseLayoutContainer = createContainer(() => {
var handle = Meteor.subscribe("user.classrooms");
return {
currentUser: Meteor.user(),
dataLoading: !handle.ready() || !Meteor.user(),
classrooms: Classrooms.find({}).fetch(),
};
}, BaseLayout);在加载之前,Meteor.user()将在组件内部是未定义的,因此请确保通过添加诸如dataLoading ? "" : Meteor.user()之类的条件来阻止它的调用。
您还可以检查用户是否使用!!Meteor.user()登录。通常,Meteor.userId()的加载速度更快,但如果需要访问用户数据,如电子邮件,则需要调用Meteor.user(),在这种情况下,不需要同时调用两者。
https://stackoverflow.com/questions/39560279
复制相似问题