【发布时间】:2018-04-05 05:24:20
【问题描述】:
我想从 AsyncStorage 加载并在我的 react 本机组件渲染期间使用它,但我的组件在应用启动时立即渲染,并且没有给 AsyncStorage 时间返回数据。
如何使用 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);
【问题讨论】:
标签: javascript android reactjs asynchronous react-native