加载 React Native 后呈现 RSS 提要数据
Rendering RSS Feed Data after Load React Native
我似乎在我的代码中缓慢加载数据时绊倒了,这阻止了我映射的自定义组件在渲染帧之前渲染 - 在相当长的时间内留下白色 space。我只是获取 rss 提要数据,对其进行解析,然后根据其 json 内容制作自定义组件。这是我的代码:
module.exports = React.createClass({
/*
mixins : [
Reflux.listenTo(FeedStore, 'onChange')
],
*/
componentWillMount: function() {
Parse.User.currentAsync()
.then((user) => { this.setState({user: user}); })
//get the latest articles on page load
//this will pre-fill out articles state
FeedStore.getArticles()
.then((data) => {
this.setState({ articles: data });
});
},
getInitialState: function() {
return {
user: null,
username: null,
articles: [],
}
},
render: function() {
var readings = this.state.articles;
return (
<ScrollView>
<ArticleView
category={'Comedy'}
key={1}
heartText={'2.9k'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_1.png')}
text={'These 3 black comedians are finally being honored for the ways they paved & the history they made'}
onPress={this.dummy} />
<ArticleView
category={'City Life'}
key={2}
heartText={'299'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_2.png')}
text={'portland forecast: approaching weekend storm could rival halloween deluge'}
onPress={this.dummy} />
<ArticleView
category={'Music'}
key={3}
heartText={'250k'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_3.png')}
text={'kendrick lamar answers furgeson criticism with new song'}
onPress={this.dummy} />
{this.renderArticleFeed(readings)}
</ScrollView>
);
},
renderArticleFeed: function(readings) {
var that = this;
//call to api to get articles from rss/api var Articles =
return readings.slice(0,4).map(function(article, i) {
console.log("========================");
console.log(article.title);
console.log(article.mediaGroups[0].contents[0].thumbnails[0].url);
return <ArticleView
category={'Music'}
key={i}
heartText={'2.9k'}
categoryPress={that.dummy}
selected={false}
source={{uri: article.mediaGroups[0].contents[0].thumbnails[0].url }}
text={article.title}
onPress={that.dummy} />
});
},
dummy: function() {
},
/*
onChange: function(event, articles) {
this.setState({articles: articles}); //trigers re-render of component
}
*/
});
我很想深入研究有助于加载数据然后呈现结果的方法——而不是在数据实际及时格式化之前立即呈现。特别是切片 readings.slice(0,4).map(function(article, i).. 函数应该处理超过 4 个 rss 提要的案例 - 我需要它能够处理所有这些,或者至少在我向下滚动时,所有部分都是这样。
我确定了一个非常有效(而且很酷)的答案!持久化来自 api 调用的数据的方法是使用 ListView, which Facebook has ok information on. A better example of it's use is documented here. Check out the associated github repo here,这在连接概念点时非常有帮助,了解它是如何工作的,所以我不会详细介绍。
这是我的新(工作代码):
var React = require('react-native');
var {
View,
Image,
StyleSheet,
Text,
ScrollView,
ActivityIndicatorIOS,
ListView,
} = React;
//additional libraries
var Parse = require('parse/react-native');
//var Reflux = require('reflux');
//dynamic component references
var ArticleView = require('./article-view/article-view');
var Api = require('../utils/api');
var FeedStore = require('../stores/feed-store');
//var Actions = require('../../actions');
//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
module.exports = React.createClass({
componentWillMount: function() {
Parse.User.currentAsync()
.then((user) => { this.setState({user: user}); })
},
getInitialState: function() {
var getSectionData = (dataBlob, sectionID) => {
console.log("SectionID GIS, getSectionData: " + sectionID);
return dataBlob[sectionID];
}
var getRowData = (dataBlob, sectionID, rowID) => {
console.log("RowID GIS, getRowData: " + rowID);
return dataBlob[sectionID + ':' + rowID];
}
return {
user: null,
isLoaded: false,
dataSource : new ListView.DataSource({
getSectionData : getSectionData,
getRowData : getRowData,
rowHasChanged : (row1, row2) => row1 !== row2,
sectionHeaderHasChanged : (s1, s2) => s1 !== s2
})
}
},
componentDidMount: function() {
this.organizeData();
},
organizeData: function() {
var data_store = null;
//get the latest articles on page load
//this will pre-fill out articles state
FeedStore.getArticles()
.then((data) => {
console.log("================");
console.log("data is at home");
console.log(data);
console.log("================");
var entries = data,
length = entries.length,
dataBlob = {},
sectionIDs = [],
rowIDs = [],
entry,
sectionID,
rowID,
i;
console.log(entries.length);
for (i = 0; i < length; i++)
{
entry = entries[i];
console.log(entry);
//add section/row to section id array
//mapping section id array for section data
sectionID = entry.title.replace(/\s+/g, '').toLowerCase() + i;
console.log("SectionID = " + sectionID);
sectionIDs.push(sectionID);
dataBlob[sectionID] = entry.title;
//mapping row id array for row data
rowIDs[i] = []
rowID = sectionID;
console.log("RowID = " + rowID);
rowIDs[i].push(rowID);
dataBlob[sectionID + ':' + rowID] = entry;
}
console.log(dataBlob);
this.setState({
dataSource : this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs),
isLoaded : true,
});
}).done();
},
render: function() {
if (!this.state.isLoaded) {
return this.renderLoadingView();
}
return this.renderListView();
},
renderLoadingView: function() {
return (
<View style={styles.container}>
<ActivityIndicatorIOS
animating={!this.state.isLoaded}
style={[styles.activityIndicator, {height: 80}]}
size="large" />
</View>
);
},
renderListView: function() {
return (
<View style={styles.container}>
<ListView
dataSource = {this.state.dataSource}
initialListSize = {4}
pageSize={4}
renderRow = {this.renderRow} />
</View>
);
},
renderRow: function (rowData, sectionID, rowID) {
console.log("Getting my rows on");
console.log(rowID);
console.log(rowData);
var that = this;
//call to api to get articles from rss/api var Articles
return <ArticleView
category={'Music'}
key={sectionID}
heartText={'2.9k'}
categoryPress={() => { that.dummy }}
selected={false}
source={{uri: rowData.mediaGroups[0].contents[0].url }}
text={rowData.title}
onPress={() => { that.dummy }} />
},
dummy: function() {
},
/*
onChange: function(event, articles) {
this.setState({articles: articles}); //trigers re-render of component
}
*/
});
styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
activityIndicator: {
alignItems: 'center',
justifyContent: 'center',
},
});
我似乎在我的代码中缓慢加载数据时绊倒了,这阻止了我映射的自定义组件在渲染帧之前渲染 - 在相当长的时间内留下白色 space。我只是获取 rss 提要数据,对其进行解析,然后根据其 json 内容制作自定义组件。这是我的代码:
module.exports = React.createClass({
/*
mixins : [
Reflux.listenTo(FeedStore, 'onChange')
],
*/
componentWillMount: function() {
Parse.User.currentAsync()
.then((user) => { this.setState({user: user}); })
//get the latest articles on page load
//this will pre-fill out articles state
FeedStore.getArticles()
.then((data) => {
this.setState({ articles: data });
});
},
getInitialState: function() {
return {
user: null,
username: null,
articles: [],
}
},
render: function() {
var readings = this.state.articles;
return (
<ScrollView>
<ArticleView
category={'Comedy'}
key={1}
heartText={'2.9k'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_1.png')}
text={'These 3 black comedians are finally being honored for the ways they paved & the history they made'}
onPress={this.dummy} />
<ArticleView
category={'City Life'}
key={2}
heartText={'299'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_2.png')}
text={'portland forecast: approaching weekend storm could rival halloween deluge'}
onPress={this.dummy} />
<ArticleView
category={'Music'}
key={3}
heartText={'250k'}
categoryPress={this.dummy}
selected={false}
source={require('../img/test_view_3.png')}
text={'kendrick lamar answers furgeson criticism with new song'}
onPress={this.dummy} />
{this.renderArticleFeed(readings)}
</ScrollView>
);
},
renderArticleFeed: function(readings) {
var that = this;
//call to api to get articles from rss/api var Articles =
return readings.slice(0,4).map(function(article, i) {
console.log("========================");
console.log(article.title);
console.log(article.mediaGroups[0].contents[0].thumbnails[0].url);
return <ArticleView
category={'Music'}
key={i}
heartText={'2.9k'}
categoryPress={that.dummy}
selected={false}
source={{uri: article.mediaGroups[0].contents[0].thumbnails[0].url }}
text={article.title}
onPress={that.dummy} />
});
},
dummy: function() {
},
/*
onChange: function(event, articles) {
this.setState({articles: articles}); //trigers re-render of component
}
*/
});
我很想深入研究有助于加载数据然后呈现结果的方法——而不是在数据实际及时格式化之前立即呈现。特别是切片 readings.slice(0,4).map(function(article, i).. 函数应该处理超过 4 个 rss 提要的案例 - 我需要它能够处理所有这些,或者至少在我向下滚动时,所有部分都是这样。
我确定了一个非常有效(而且很酷)的答案!持久化来自 api 调用的数据的方法是使用 ListView, which Facebook has ok information on. A better example of it's use is documented here. Check out the associated github repo here,这在连接概念点时非常有帮助,了解它是如何工作的,所以我不会详细介绍。
这是我的新(工作代码):
var React = require('react-native');
var {
View,
Image,
StyleSheet,
Text,
ScrollView,
ActivityIndicatorIOS,
ListView,
} = React;
//additional libraries
var Parse = require('parse/react-native');
//var Reflux = require('reflux');
//dynamic component references
var ArticleView = require('./article-view/article-view');
var Api = require('../utils/api');
var FeedStore = require('../stores/feed-store');
//var Actions = require('../../actions');
//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
module.exports = React.createClass({
componentWillMount: function() {
Parse.User.currentAsync()
.then((user) => { this.setState({user: user}); })
},
getInitialState: function() {
var getSectionData = (dataBlob, sectionID) => {
console.log("SectionID GIS, getSectionData: " + sectionID);
return dataBlob[sectionID];
}
var getRowData = (dataBlob, sectionID, rowID) => {
console.log("RowID GIS, getRowData: " + rowID);
return dataBlob[sectionID + ':' + rowID];
}
return {
user: null,
isLoaded: false,
dataSource : new ListView.DataSource({
getSectionData : getSectionData,
getRowData : getRowData,
rowHasChanged : (row1, row2) => row1 !== row2,
sectionHeaderHasChanged : (s1, s2) => s1 !== s2
})
}
},
componentDidMount: function() {
this.organizeData();
},
organizeData: function() {
var data_store = null;
//get the latest articles on page load
//this will pre-fill out articles state
FeedStore.getArticles()
.then((data) => {
console.log("================");
console.log("data is at home");
console.log(data);
console.log("================");
var entries = data,
length = entries.length,
dataBlob = {},
sectionIDs = [],
rowIDs = [],
entry,
sectionID,
rowID,
i;
console.log(entries.length);
for (i = 0; i < length; i++)
{
entry = entries[i];
console.log(entry);
//add section/row to section id array
//mapping section id array for section data
sectionID = entry.title.replace(/\s+/g, '').toLowerCase() + i;
console.log("SectionID = " + sectionID);
sectionIDs.push(sectionID);
dataBlob[sectionID] = entry.title;
//mapping row id array for row data
rowIDs[i] = []
rowID = sectionID;
console.log("RowID = " + rowID);
rowIDs[i].push(rowID);
dataBlob[sectionID + ':' + rowID] = entry;
}
console.log(dataBlob);
this.setState({
dataSource : this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs),
isLoaded : true,
});
}).done();
},
render: function() {
if (!this.state.isLoaded) {
return this.renderLoadingView();
}
return this.renderListView();
},
renderLoadingView: function() {
return (
<View style={styles.container}>
<ActivityIndicatorIOS
animating={!this.state.isLoaded}
style={[styles.activityIndicator, {height: 80}]}
size="large" />
</View>
);
},
renderListView: function() {
return (
<View style={styles.container}>
<ListView
dataSource = {this.state.dataSource}
initialListSize = {4}
pageSize={4}
renderRow = {this.renderRow} />
</View>
);
},
renderRow: function (rowData, sectionID, rowID) {
console.log("Getting my rows on");
console.log(rowID);
console.log(rowData);
var that = this;
//call to api to get articles from rss/api var Articles
return <ArticleView
category={'Music'}
key={sectionID}
heartText={'2.9k'}
categoryPress={() => { that.dummy }}
selected={false}
source={{uri: rowData.mediaGroups[0].contents[0].url }}
text={rowData.title}
onPress={() => { that.dummy }} />
},
dummy: function() {
},
/*
onChange: function(event, articles) {
this.setState({articles: articles}); //trigers re-render of component
}
*/
});
styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
activityIndicator: {
alignItems: 'center',
justifyContent: 'center',
},
});