我正在使用React和Meteor。
在顶层我有一个MainWrapper组件。它显示加载,如果用户数据没有到达,登录/注册,如果没有用户,然后显示真实页面,如果它有所有用户数据。
这是为了防止使用Meteor.user()的组件在数据到达时重新渲染之前的一小段时间内未定义。
所以,关于真正的问题:
这是MainWrapper的底部。
export default createContainer(() => {
return {
user: Meteor.user(),
};
}, MainWrapper);
每个用户帐户文档都有一个配置文件属性,包含名字,朋友,通知等。所以我需要在应用程序周围提供这些数据。
我最好将用户从MainWrapper中作为道具传递下来吗?
或者我应该在每个需要它的组件中订阅该数据? (或者我甚至需要订阅?如果组件只在MainWrapper确保用户可用时才加载,那么我可以在组件中使用Meteor.user()而无需额外开销吗?)
非常感谢任何帮助!
答案 0 :(得分:1)
好问题!
一般来说,您想知道如何管理您的应用程序状态。有州管理库(Flux,Redux等)。它们处理您的状态,您的组件订阅了状态的更改。
我最好将用户从MainWrapper中作为道具传递下来吗?
以这种方式执行它必须将道具传递给每个子组件。想象一下你有A - > B - > C - > D组件。
如果要将用户对象从A传递给D,则必须确保B和C也通过。它的错误是友好的,因为你很容易忘记在很长一段时间内传递它。但是,这里的一个大问题是您使所有组件都依赖于用户对象。想象一下,你想在其他地方重用B组件,但它是否依赖于用户对象?
让我们使用Redux(我有使用它的经验)。您可以将组件分离为演示文稿和容器。简而言之,演示组件没有订阅商店(您的州),您可以在任何地方重复使用它们。另一方面,Container组件被包含在Store中,并且它们将props传递给包含的子节点演示组件。
这里有一些关于演讲和演讲的好读物。容器组件:
因此,组件分离的想法也可以在Meteor中实现。例如,您的Meteor应用程序将充当API,而Redux将处理前端应用程序逻辑和状态。有不同的实现。这是good read如何将Redux集成到Meteor中。
当然,您可以跳过Redux(或任何其他状态库)并使用Meteor工具集实现组件分离。
请记住我的答案是React& Redux经验丰富,为您提供了如何更好地组织组件的一般想法。
答案 1 :(得分:0)
我认为在客户端but let's double check上调用Meteor.user()
会有一些开销。在服务器上肯定有一个,因为这会查询数据库,但除非你做服务器端渲染,否则这不是一个问题。
因此,如果您定义的Meteor.user()
组件仅在用户加载后呈现,则只需在需要时查询Meteor.user()
。
另一种方法是使用React context传递此信息。该文档列出了一些警告,并说它是一个实验性功能。我已经使用了一段时间,我对它非常满意。它是为了解决@Jordan提到的问题,当你有一个必须将父道具传递给他们孩子的组件列表时。这看起来像是:
export class MainWrapper extends Component {
// specify some properties to make available to all descendant
getChildContext() {
return {
currentUser: Meteor.user(),
};
}
}
MainWrapper.childContextTypes = { currentUser: PropTypes.object };
class SomeComponent extends Component {
render() {
const user = this.context.currentUser;
...
}
};
我实际上更喜欢第二种方法,因为它很好地将UI与数据依赖关系分开,并使您的组件更容易测试Meteor上下文。由此决定你是否需要还原剂。
更一般地说,您可能希望查看在UI角色/数据状态角色中分隔反应对象的容器/组件结构。如果你这样做,你应该在容器部分进行Meteor.user()
取件。我推荐它。 React Komposer使您可以轻松完成,并允许您指定在加载数据时呈现的占位符组件:1,2。您可能也对my fork感兴趣,特别是处理React上下文,但与主仓库并不是最新的。