React 不会渲染递归反应式组件
React does not render recursive reactive components
给定此组件:
import React, { Component } from 'react';
import TrackerReact from 'meteor/ultimatejs:tracker-react';
export default class SubscriptionView extends TrackerReact(Component) {
constructor(props) {
super(props);
let params = props.params || [];
if (!Array.isArray(params)) {
params = [params];
}
this.state = {
subscription: {
collection: Meteor.subscribe(props.subscription, ...params)
}
};
}
componentWillUnmount() {
this.state.subscription.collection.stop();
}
render() {
let loaded = this.state.subscription.collection.ready();
if (!loaded) {
return (
<section className="subscription-view">
<h3>Loading...</h3>
</section>
);
}
return (
<section className="subscription-view">
{ this.props.children }
</section>
);
}
};
另一个组件:
import SubscriptionView from './SubscriptionView.jsx';
export const Foo = () => (
<SubscriptionView subscription="allFoo">
<SubscriptionView subscription="singleBar" params={ 123 }>
<div>Rendered!</div>
</SubscriptionView>
</SubscriptionView>
);
第一个Subscription
在数据可用时重新呈现,但第二个只呈现一次,仅此而已。如果我在 SubscriptionView
的渲染函数中放置一个console.log(this.props.subscription, ready);
,我会看到
allFoo false
allFoo true
singleBar false
仅此而已。
在服务器端,两种发布方法都是
Meteor.publish('allFoo', function () {
console.log("Subscribing foos");
return Foos.find();
});
Meteor.publish('singleBar', function (id) {
console.log("Subscribing bar", id);
return Bars.find({ _id: id });
});
正在调用这两个发布方法。
为什么第二SubscriptionView
不是被动的?
*溶液*
这是基于alexi2的评论:
import React, { Component } from 'react';
import TrackerReact from 'meteor/ultimatejs:tracker-react';
export default class SubscriptionLoader extends TrackerReact(Component) {
constructor(props) {
super(props);
let params = props.params || [];
if (!Array.isArray(params)) {
params = [params];
}
this.state = {
done: false,
subscription: {
collection: Meteor.subscribe(props.subscription, ...params)
}
};
}
componentWillUnmount() {
this.state.subscription.collection.stop();
}
componentDidUpdate() {
if (!this.state.done) {
this.setState({ done: true });
this.props.onReady && this.props.onReady();
}
}
render() {
let loaded = this.state.subscription.collection.ready();
if (!loaded) {
return (
<div>Loading...</div>
);
}
return null;
}
};
然后,在父组件的 render
方法中:
<section className="inventory-item-view">
<SubscriptionLoader subscription='singleBar' params={ this.props.id } onReady={ this.setReady.bind(this, 'barReady') } />
<SubscriptionLoader subscription='allFoos' onReady={ this.setReady.bind(this, 'foosReady') } />
{ content }
</section>
其中setReady
仅设置组件的状态,并且仅当this.state.barReady && this.state.foosReady
为 true 时,content
才具有值。
它有效!
尝试像这样分离出SubscriptionView
组件:
import SubscriptionView from './SubscriptionView.jsx';
export const Foo = () => (
<div>
<SubscriptionView subscription="singleBar" params={ 123 }>
<div>Rendered!</div>
</SubscriptionView>
<SubscriptionView subscription="allFoo">
<div>Rendered Again!</div>
</SubscriptionView>
</div>
);
从评论对话编辑
不确定我是否走在正确的轨道上,但您可以将 Foo 构建为一个"智能"组件,根据需要将 props 传递给每个 SubscriptionView,然后将 Foo 用作可重用组件。
假设我需要渲染的是FooBarForm,它要求在该特定用例中同时注册Foos和Bars。你会怎么做?
您可以根据需要创建组件Foos
和Bars
,并创建一个包含这些组件并传递必要数据的父组件FooBarForm
。
FooBarForm
将处理状态,并在更改时将其传递给其子组件的 props。
现在,状态由父组件集中管理,子组件使用从父组件传递的 props 进行渲染。
子组件将在其 props 更改时重新渲染,具体取决于从父组件传递的状态是否已更改。
相关文章:
- 数组在递归方法中设置为null
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 递归使用 eval() 是检查程序执行的好方法吗?
- 使用递归、Ramda.js和无点样式重构字符串的getPermutations()
- 递归深度比较
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 递归函数中断
- 如何递归地获取嵌套对象中所有子对象的列表
- JavaScript 素数搜索无限递归
- 在递归生成器函数中,yield后面的*(星号/星号)语法意味着什么
- 递归|两个函数名
- 使用代码了解 JavaScript 中的反应式扩展
- 有没有一种方法可以在Javascript中进行可变递归currying
- 如何对不同的表递归使用以下代码
- 将jQuery对象传递到setTimeout递归函数中
- 有更好的方法吗?(递归解析HTML unicode实体)
- 递归,而不显式设置变量javascript
- 在nodejs中使用瀑布式和递归异步
- 递归承诺链末端的链式动作
- React 不会渲染递归反应式组件