我正在创建一个应用程序,该应用程序应该在某个时刻获取带有标题,描述和用户信息的信息提要。我正在做反应本机,这也是同一视图中的两个独立的源,可以在两个选项卡之间切换,所以我认为我当前的架构随后将是最佳的。
手头的问题:
来自Methods.js:
exports.getFriendFeed = function(TOKEN) {
return new Promise((resolve, reject) => {
fetch(baseUrl + 'feed' , {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Token' : TOKEN,
},
})
.then((response) => response.text())
.then((responseText) => {
resolve(responseText);
})
.catch((error) => {
reject(error);
});
});
};
我写了获取请求并将其发送到我的home.js屏幕。并按如下方式处理:
var Home = React.createClass({
.
.
.
changeComponent: function(component) {
Method.getFriendFeed(this.state.tokenSupreme)
.then((res) => this.setState({
friendFeed: JSON.parse(res).friendPosts,
loaded: true,
}))
.catch((error) => console.log(error))
.done();
this.setState({
componentSelected: component,
})
},
这意味着当我按下某个Feed视图时,内容会专门为该视图加载。
渲染组件并传递信息源的道具以及是否已加载:
renderComponent: function(component) {
if(component === 'One') {
return <ComponentOne
friendData={
this.state.friendFeed
}
loaded={
this.state.loaded
} />
} else if(component === 'Two') {
return <ComponentTwo />
}
},
但现在出现了真正的问题。遵循React Native提供的文档。我有console.log
'对rowData产生“加载”,然后它返回我想要的json格式数据。所以这意味着它首先成功通过changeComponent
函数并变为“加载”,并错误地将this.state.loaded
变为true
,这意味着在此期间有一个时间点这个执行,我不能在我的json中调用任何特定的键或名称,因为它只加载了“种类”,它只是立即返回未定义和红色屏幕应用程序。
var ComponentOne = React.createClass({
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
dataSource: ds.cloneWithRows(this.props.friendData),
};
},
render: function() {
if (!this.props.loaded) {
return this.renderLoadingView();
} else {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.card} />
)
}
},
renderLoadingView: function() {
return (
<View style={{alignItems: 'center', alignSelf: 'center', marginTop: 150, justifyContent: 'center'}} >
<Text style={{fontSize: 30, fontWeight: '400', color: '#666'}}> Loading ... </Text>
</View>
);
},
renderRow: function(rowData) {
return (
<CardView
name={rowData.name}
fullname='xyz'
distance='xyz'
title={rowData.title}
message={rowData.description}
score='xyz'
stars='xyz'
starcolors={colors.General.black}
vouched="Example" />
)
}
})
为什么它给我这个?如果我把fetcher放在componentDidMount中,并且如果我将它放在渲染中,那么它永远不会真正激发。它会无限制地激发。
如何更有效地控制此执行/生命周期问题?我也尝试将其作为IF语句说if (this.props.friendFeed.friend.name !== undefined)
,但不管你信不信,它只是返回一个红色屏幕,上面写着this.props.friendFeed.friend.name is undefined
。在密钥中调用对象可能是一个问题吗?我可以在定义之前调用这样的东西,而不是它被定义吗?
答案 0 :(得分:0)
我看到两种可能的解决方案。首先,关于在未定义对象上调用键的最后一个问题。考虑这个对象......
{
foo: {
bar: 'text'
}
}
如果在任何时候foo
为undefined
,则无法检查子对象键是否也是undefined
。您需要确定在加载数据时可能未定义的最高根对象。
因此,如果if (foo.bar !== undefined)
为foo
,则此语句将失败:undefined
。但是,这句话没问题:if (foo.hasOwnProperty('bar'))
或技术上甚至是if (foo !== undefined)
。
至于你的主要问题,我的猜测是数据解析会发生异步事件。这就是我实现fetch
...
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response.text().then((text) => {
if (text == "") return ""
return JSON.parse(text)
})
return response.json()
}
}
get(id, query) {
let url = this.API_URL() + '/' + id + this._generateQuery(query)
return fetch(url, {
method: 'get',
headers: this._headers()
}).then(this._checkStatus)
.then((data) => {
return data
})
}
请注意我如何利用将正文处理成文本的承诺方面。我会尝试在changeComponent
中执行类似的操作,以便它不会调用setState
(并随后将加载设置为true),直到您确定数据已被解析为止。由于它是内联的,它可能会立即调用setState
,然后在完成解析时短时间内呈现具有不完整数据的组件(因为它只是传递变量引用,而不是值)。