使用AsyncStorage + React Native在初始加载后更快地重新加载RSS Feed内容

时间:2015-12-15 13:31:05

标签: performance asynchronous rss react-native

我对AsyncStorage的使用非常陌生,我想确保我以正确的方式在我的代码中使用它。我正在尝试加速我的应用程序中的各种加载过程,这实际上是一个媒体应用程序,它采用各种RSS源,根据用户的兴趣过滤它们,并创建自定义的内容源。

第一次,我使用来自所选rss feed的promises数组进行fetch,然后返回自定义组件中的数据。返回的文章数组中的项目是随机的(似乎不是静态的),但我只想加载和随机化一次文章数组。

以下是在自定义组件中加载rss Feed的代码:

var React = require('react-native');
var {
    View, 
    Image,
    StyleSheet,
    Text, 
    ListView, 
    TouchableHighlight, 
    AsyncStorage, 
} = React;

//additional libraries
var Parse = require('parse/react-native');
//var Reflux = require('reflux');

//dynamic component references
var ArticlePreview = require('./exp_base_components/article-preview');
var Api = require('../utils/api');
var FeedStore = require('../stores/feed-store');
var ArticleDetails = require('./exp_base_components/article-details');
var Spinner = require('react-native-spinkit');
//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}); })
    },  
    componentDidMount: function() {
        //console.log(this.state.user);
        var personalFeed = null; 
        var Onboarding = Parse.Object.extend("Onboarding");
        var query = new Parse.Query(Onboarding);
        query.equalTo("userObjectId", Parse.User.current());
        var that = this;
        query.find({
          success: function(result) {
            console.log("Successfully retrieved " + result.length + " users!");
            var object = result[0];
            console.log(object.id);
            // Do something with the returned Parse.Object values
            console.log(object.get('interests'));
            that.fetchData(object.get('interests'));
          },
          error: function(error) {
            console.log("Error: " + error.code + " " + error.message);
          }
        });

    },
    getInitialState: function() {
        return {
            user: null, 
            personalFeed: null, 
            isLoaded: false, 
            dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2,
            }), 
        }
    },
    fetchData: function(personalFeed) {
        var that = this; 
        FeedStore.getArticles(personalFeed)
            .then((data) => {
                var entries = data; 
                that.setState({
                    dataSource : that.state.dataSource.cloneWithRows(entries),
                    isLoaded   : true, 
                });
            }).done();
    }, 
    render: function() {

        if (!this.state.isLoaded) {
            return this.renderLoadingView();
        }
        return this.renderListView();
    }, 
    renderLoadingView: function() {
        return (
            <View style={styles.container}>
                <Spinner style={styles.spinner} isVisible={!this.state.isLoaded} size={50} type={'Arc'} color={'#FF0000'}/>
            </View>
        );
    }, 
    renderListView: function() {
        return (
            <View style={styles.container}>
                <ListView
                    dataSource = {this.state.dataSource}
                    initialListSize = {5}
                    pageSize={5}
                    renderRow  = {this.renderEntry} />
            </View>
        );
    }, 
    renderEntry: function(entry) {

        if (typeof entry.mediaGroups === 'undefined')
        {
            return (
                <ArticlePreview
                    category={entry.categories[0]}
                    key={entry.title}
                    heartText={'2.9k'}
                    categoryPress={this.onCategoryDetailsPress}
                    selected={false}
                    source={require('../img/stock_image.png')}
                    text={entry.title.toLowerCase().replace('&nbsp;','')}
                    onPress={() => this.onArticleDetailsPress(entry)} />
            );
        } else 
        { 
            var url = entry.mediaGroups[0].contents[0].url; 
            if (url.indexOf('w=150') > -1)
            {
                url.replace("w=150", "w=500");
            }
            var catsource = entry.categories[0]; 
            if (typeof catsource == "undefined")
            {
                catsource = "News";
            }
            return (
                <ArticlePreview
                    category={catsource}
                    key={entry.title}
                    heartText={'2.9k'}
                    categoryPress={this.onCategoryDetailsPress}
                    selected={false}
                    source={{uri: url }}
                    text={entry.title.toLowerCase().replace('&nbsp;','')}
                    onPress={() => this.onArticleDetailsPress(entry)} />
            );
        }

    },
    onCategoryDetailsPress: function() {
        //forward to sytled web view of categorical article feed
        console.log("onCategoryDetailsPress"); 
    }, 
    onArticleDetailsPress: function(entry) {
        //forward to sytled web view of article details given link
        console.log("onArticleDetailsPress"); 
        console.log(entry);

        this.props.navigator.immediatelyResetRouteStack([{
            name: 'articledetails',
            passProps: {entry: entry},
        }]);
    }, 
    /*
    onChange: function(event, articles) {
        this.setState({articles: articles}); //trigers re-render of component
    }
    */

});


styles = StyleSheet.create({
    container: {
        flex: 1, 
        alignItems: 'center', 
        justifyContent: 'center',
        backgroundColor: '#000000', 
    }, 
    activityIndicator: {
        alignItems: 'center',
        justifyContent: 'center',
    },
    spinner: {
        marginBottom: 50,
    },
});

这是加载顺序:

enter image description here

有没有办法在此过程中合并AsyncStorage,以便当用户再次访问该帧时(第二次+时间),数据可以加载更快?

1 个答案:

答案 0 :(得分:2)

您可以将数据保存在AsyncStorage中,如下所示:

  const STORAGE_KEY = 'yourkey';

  fetchData: function(personalFeed) {
        var that = this; 
        FeedStore.getArticles(personalFeed)
            .then((data) => {
                var entries = data; 
                // Set a key for AsyncStorage, and Stringify the data
                AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(data))
                that.setState({
                    dataSource : that.state.dataSource.cloneWithRows(entries),
                    isLoaded   : true, 
                });
            }).done();
  }

然后像这样检索它:

AsyncStorage.getItem(STORAGE_KEY)
  .then((storedData) => {
    var parsedData = JSON.parse(storedData)  
    // do something with the parsedData
  })
  .catch((err) => {
     // Could set the AnsyncStorage key here since it was not found.
  })