我在我的应用中遇到了一些非常不受欢迎的行为,而且我很难复制问题和/或弄清楚我做错了什么或不了解React&# 39; s导致我的组件以这种方式行动。
我想要做的是在App组件上从Mongo获取一些数据,然后让所有这些数据随时可用于我想要的任何孩子。
<App> //get data here, pass to children through props
<ChildElement1 data={this.data.appData}/>
<ChildElement2 data={this.data.appData}/>
<ChildElement3 data={this.data.appData}/>
</App>
到目前为止,我是如何尝试使用React解决这个问题的:
App = React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
let _id = 'exampleId';
return {
appData: Collection.findOne({_id})
};
},
render() {
return (<ChildElement1 data={this.data.appData} />);
}
});
ChildElement1 = React.createClass({
getInitialState() {
return {
values: ['val1', 'val2', 'val3', 'val4'] //default values
};
},
componentWillMount() {
if(this.props.data.specificValues) {
this.setState({values: this.props.data.specificValues});
}
},
render() {
let values = this.state.values;
return (<span>{values[0]} {values[1]} {values[2]} {values[3]}</span>);
}
});
所以在这里它变得奇怪。当我拨打componentWillMount()
时,有时会定义this.props.data
,有时会定义componentWillReceiveProps(nextProps)
,这会让我相信某些竞争条件正在进行,有时数据会被加载正确地作为道具而其他时候它没有。
然后我认为,好吧,在组件最初安装之前,我不能依赖于数据道具,所以我可以改用componentWillReceiveProps
并检查更新的道具(和如有必要,更新状态)。然而!使用this.props.data
后,现在ChildElement1
似乎始终正确附加到componentWillReceiveProps
的道具上(这意味着componentWillMount
无法运行!)。
我的最终解决方案是同时使用componentWillReceiveProps
和componentWillMount
来解释这两种情况并在两个位置进行完全相同的检查。这个修复工作正常,但是男孩看起来很麻烦,可能表示对组件生命周期缺乏了解,流星/反应应该如何正确地进行交互,两者都完全相互作用。
我在这里肯定会有点帮助。
编辑:我提出了一个小改进 - 而不是使用componentWillReceiveProps
和render
来检查是否在Mongo集合中定义了特定值,我把render() {
let data = this.props.data,
values = (data) ? data.specificValues : this.state.values;
return (<span>{values[0]} {values[1]} {values[2]} {values[3]}</span>);
}
中的逻辑如此:
this.props
但是,由于我仍然不明白为什么getMeteorData
在从async's map
检索到数据时如此不一致,所以仍然存在某种潜在的问题。然而,这个版本有点简洁。
答案 0 :(得分:0)
我找到了一个更好的方法,而不是将getMeteorData
返回的数据作为道具传递给每个孩子。使用此处描述的方法:https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html,我在childContextTypes
中明确列出了getChildContext
和<App />
,然后在contextTypes
中明确列出<ChildElement1 />
,这允许{ {1}} this.data.appData
this.context
<ChildElement1 />
可能<App />
可能angular
.module('app')
.factory('stats', function($http){
return {
getStats: function(path) {
return $http
.get(path)
.then(function(result) {
//resolve the promise as the data
return result.data;
});
}
};
});
。虽然我必须承认,声明该集合的每个单一类型都是一个主要的PITA,似乎有必要编写一个mixin(或者更确切地说,一堆mixins)来处理这些东西。