从API提取时如何存储数据

时间:2019-01-05 18:52:38

标签: javascript android ios reactjs react-native

我创建了一个从URL检索数据并显示它的应用程序。我是初学者,因此暂时不使用Redux或其他工具。

我设法恢复了数据并将其显示在我的应用程序中,但是我想使用手机的本地存储。我在Expo网站的文档中看到了有关AsyncStorage的示例,但是我不知道如何使它们适应我的代码。另外,仅在没有互联网连接时才需要显示本地存储数据吗?还是我仍然必须始终显示它们?

import React, {Component} from 'react';
import {ScrollView, View, FlatList, Image, ActivityIndicator} from 'react-native';
import {ListItem} from "react-native-elements";
import {createAppContainer, createStackNavigator} from "react-navigation";
import PronosticsDetailsScreen from "../../screens/PronosticsDetailsScreen";
import AppConfig from "../../AppConfig";

class MontanteTab extends Component {

    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
        };
    }

    componentDidMount() {
        return fetch('https://myurl.com')
            .then((response) => response.json())
            .then((responseJson) => {
                this.setState({
                    isLoading: false,
                    dataSource: responseJson
                }, function () {

                });
            })
            .catch((error) => {
                console.error(error);
            });
    }

    render() {
        if (this.state.isLoading === true) {
            return (
                <View style={{flex: 1, padding: 20}}>
                    <ActivityIndicator/>
                </View>
            )
        }

        return (
            <View>
                <ScrollView>
                    <View>
                        <FlatList
                            data={this.state.dataSource}
                            keyExtractor={(item, index) => index.toString()}
                            renderItem={({item}) => (
                                <ListItem
                                    key={item.id}
                                    roundAvatar
                                    badge={{
                                        value: item.statut,
                                        textStyle: {color: '#fff'},
                                        containerStyle: {marginRight: 0, backgroundColor: item.couleur}
                                    }}
                                    avatar={<Image
                                        source={{uri: 'https://myurl.com/' + item.image}}
                                        style={{borderRadius: 50, height: 50, width: 50}}/>}
                                    title={item.competition}
                                    subtitle={item.equipe_domicile + ' - ' + item.equipe_exterieur}
                                    onPress={() => this.props.navigation.navigate('PronosticsDetails', {
                                        item,
                                    })}
                                />
                            )}
                        />
                    </View>
                </ScrollView>
            </View>
        );
    }
}

编辑:

我尝试了此操作,但是我的数据没有显示:

import React, {Component} from 'react';
import {ScrollView, View, FlatList, Image, ActivityIndicator, AsyncStorage} from 'react-native';
import axios from "axios";
import {ListItem} from "react-native-elements";
import {createAppContainer, createStackNavigator} from "react-navigation";
import AppConfig from "../../AppConfig";
import Keys from "../../data/Constants/Storage";
import PronosticsDetailsScreen from "../../screens/PronosticsDetailsScreen";

class MontanteTab extends Component {

    state = {
        errors: null,
        isLoading: true,
        pronostics: [],
    };

    async componentDidMount() {
        const isConnected = true;

        if (isConnected) {
            await this.loadPronostics();
        }

        try {
            this.setState({pronostics: JSON.parse(await AsyncStorage.getItem(Keys.pronosticsMontante))});
        } catch (error) {
            console.log(error);
        }
    }

    loadPronostics() {
        this.setState({isLoading: true, error: null});

        return axios.get(AppConfig.apiUrl + 'montante').then(async response => {
            await AsyncStorage.setItem(Keys.pronosticsMontante, JSON.stringify(this.state.pronostics));
            this.setState({isLoading: false});
        }).catch(error => {
            this.setState({isLoading: false, error: error.response});
            console.log(error);
        });
    }

    render() {
        if (this.state.isLoading === true) {
            return (
                <View style={{flex: 1, padding: 20}}>
                    <ActivityIndicator/>
                </View>
            )
        }

        return (
            <View>
                <ScrollView>
                    <View>
                        <FlatList
                            data={this.state.pronostics}
                            keyExtractor={(item, index) => index.toString()}
                            renderItem={({item}) => (
                                <ListItem
                                    key={item.id}
                                    roundAvatar
                                    badge={{
                                        value: item.statut,
                                        textStyle: {color: '#fff'},
                                        containerStyle: {marginRight: 0, backgroundColor: item.couleur}
                                    }}
                                    avatar={<Image
                                        source={{uri: AppConfig.imagesPronosticsUrl + item.image}}
                                        style={{borderRadius: 50, height: 50, width: 50}}/>}
                                    title={item.competition}
                                    subtitle={item.equipe_domicile + ' - ' + item.equipe_exterieur}
                                    onPress={() => this.props.navigation.navigate('PronosticsDetails', {
                                        item,
                                    })}
                                />
                            )}
                        />
                    </View>
                </ScrollView>
            </View>
        );
    }
}

3 个答案:

答案 0 :(得分:3)

您可以使用React Native AsyncStorage将数据存储到设备的本地存储中。

import { AsyncStorage } from 'react-native'

使用它来保存数据

AsyncStorage.setItem('key', 'value');

AsyncStorage接受值作为唯一字符串,因此您可能需要在将值设置为AsyncStorage之前使用stringify()

并使用获取数据

AsyncStorage.getItem('key'); 
  

代码:

const KEY = 'USER_DATA'

let keyValue = { name: yogi }

AsyncStorage.setItem(KEY,keyValue);

AsyncStorage.getItem(KEY).then(asyncStorageRes => {
    console.log(JSON.parse(asyncStorageRes))
});

答案 1 :(得分:1)

因为这是一个React Native项目,所以我认为subject是您想要的。您可以在AsyncStorage的空setState回调中设置值。如果只需要在会话结束时存储数据,则可以使用componentDidMount并在nextState为后台或非活动状态时设置值。 AppStateAsyncStorage.getItem()处于活动状态时,请使用AppState。  https://facebook.github.io/react-native/docs/appstate https://facebook.github.io/react-native/docs/asyncstorage

答案 2 :(得分:0)

这取决于您的列表数据更改的频率,

如果列表数据是恒定的,则可以将API响应存储在本地存储中。然后显示本地存储中的列表数据。

如果列出的数据经常更改,您仍然可以使用本地存储。根据API响应将数据存储在本地存储中。 下次页面加载时,显示本地存储中的数据,并进行API调用以获取最新数据,并在API响应显示数据中列出并更新本地存储中的数据。 使用这种方式,用户将不必等待API响应。

对于存储数据,可以使用JavaScript语法localStorage.setItem('key', 'apiresponse')localStorage.getItem('key')

OR

可以创建Service类,该类将API响应存储在对象中,也可以在其他文件中使用。