javascript - 加载 React Native 后渲染 RSS 提要数据

标签 javascript rss loading react-native custom-component

我似乎在代码中缓慢加载数据,这导致我的映射自定义组件在帧渲染之前无法渲染 - 在相当长的时间内留下空白。我只是获取 rss feed 数据,对其进行解析,然后根据其 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
    }
    */

});

我很乐意深入研究有助于加载数据,然后渲染结果的方法,而不是在数据实际及时格式化之前立即渲染。特别是 slice Readings.slice(0,4).map(function(article, i).. 函数应该处理 rss feed 的 4 个以上的案例 - 我需要它能够处理所有的案例,或者至少当我向下滚动时,所有这些都分成了部分。

最佳答案

我确定了一个非常有效(而且很酷)的答案!保存来自 api 调用的数据的方法是使用 ListView ,Facebook 上有不错的信息。其使用的更好示例记录在 here 中。 。查看关联的 github 存储库 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',
    },
});

关于javascript - 加载 React Native 后渲染 RSS 提要数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34223805/

相关文章:

javascript - 在远程 Angular 应用程序中下载时 Excel 文件损坏

ruby-on-rails - 将西类牙语 feed 翻译成英语,然后存储到 MYSQL 数据库中

c# - 可用于 ASP.NET Core 的 RSS/Atom 提要阅读器

c - 调用进程的符号查找?

angularjs - 您如何检测 AngularJS 中的 HTML 渲染何时完成

javascript - 如何更新 ACE 编辑器中的值 : javascript

javascript - 如何将参数传递给 Node js 中的函数

java - Head First Android 开发 - RSS 提要

ios - UIWebview的动态加载

javascript - 需要与 document.ready 相反的 jQuery