我希望从AsyncStorage中加载数据并在我的React Native组件渲染期间使用它,但我的组件会立即在应用启动时呈现,没有给AsyncStorage返回数据的时间。
如何使用AsyncStorage使我的组件要么A)等待正确的信息被渲染或B)一旦数据加载完毕就改变以反映正确的信息?
如何使用AsyncStorage使我的组件要么A)等待正确的信息被渲染或B)一旦数据加载完毕就改变以反映正确的信息?
import React from 'react';
import { AsyncStorage } from 'react-native';
// my wrapper object around AsyncStorage
export default class StorageManager {
constructor() {
this.data = {
settings: { },
}
this.loadSettings();
}
async loadSettings() {
await AsyncStorage.getItem('settings')
.then( (settings) => this.data.settings = JSON.parse(settings) )
.catch( (err) => console.log(err) );
}
/*
* settings = {days: number, currency: string, costPerDay: number }
*/
getDays() {
return this.data.settings.days;
}
}
以下是我的组件代码。首先呈现的是AchievementScreen,此时StorageManager没有时间加载任何内容。当我切换到其他屏幕时才会呈现它们,因此它们都已正确加载好了。
import React, {Component} from 'react';
import {AppRegistry, StyleSheet, Alert} from 'react-native';
import { Container, Header, Content, Body, List, Text} from 'native-base';
import { Col, Row, Grid } from "react-native-easy-grid";
import AchievementCard from '../../components/AchievementCard/AchievementCard'
export default class AchievementScreen extends Component {
constructor(props) {
super(props);
// debugger shows props.storageManager as well-shaped but empty.
this.state = {
storageManager: this.props.storageManager,
achievementCards: [ this.moneySavedAchievement(props.storageManager),
{header: "Header 2", body: "Body 2", icon: "money"},
]
}
}
moneySavedAchievement(storageManager) {
return {
header: "Money Saved",
body: storageManager.data.settings.currency +
storageManager.data.settings.costPerDay *
storageManager.data.settings.days,
icon: "money"
}
}
render() {
return (
<Container>
<Content>
<Grid>
<Col>
<List dataArray={this.state.achievementCards.slice(0, this.state.achievementCards.length / 2)}
renderRow={ (item) =>
<AchievementCard achievementHeader={item.header}
achievementBody={item.body}
achievementIcon={item.icon} />
}
/>
</Col>
<Col>
<List dataArray={this.state.achievementCards.slice(this.state.achievementCards.length / 2)}
renderRow={ (item) =>
<AchievementCard achievementHeader={item.header}
achievementBody={item.body}
achievementIcon={item.icon} />
}
/>
</Col>
</Grid>
</Content>
</Container>
);
}
}
AppRegistry.registerComponent('AchievementScreen', () => AchievementScreen);
我的主页应用程序代码
import React, {Component} from 'react';
import {AppRegistry, StyleSheet} from 'react-native';
import {Tabs, Tab, Container, Header, Title, Body, TabHeading, Text, Right, Left, Button, TouchableOpacity} from 'native-base';
import Icon from 'react-native-vector-icons/FontAwesome';
import HomeScreen from './app/screens/HomeScreen/HomeScreen';
import MilestoneScreen from './app/screens/MilestoneScreen/MilestoneScreen';
import AchievementScreen from './app/screens/AchievementScreen/AchievementScreen';
import StorageManager from "./app/modules/StorageManager/StorageManager";
export default class my_react_app extends Component {
constructor() {
super();
this.state = {
storageManager: new StorageManager()
}
}
render() {
return (
<Container>
<Header hasTabs>
<Left />
<Body>
<Title>My App</Title>
</Body>
<Right>
<Icon active name="ellipsis-v" color="white"/>
</Right>
</Header>
<Tabs initialPage={0}>
<Tab heading="Status">
<AchievementScreen storageManager={this.state.storageManager} />
</Tab>
<Tab heading="Progress">
<HomeScreen storageManager={this.state.storageManager} />
</Tab>
<Tab heading="Milestones">
<MilestoneScreen storageManager={this.state.storageManager} />
</Tab>
</Tabs>
</Container>
);
}
}
AppRegistry.registerComponent('my_react_app', () => My_React_App);