Javascript 如何在启动时使用异步存储数据呈现React本机组件?
我想从AsyncStorage加载并在react本机组件呈现期间使用它,但我的组件在应用程序启动时立即呈现,并且没有给AsyncStorage返回数据的时间 如何使用AsyncStorage使我的组件可以A)等待呈现,直到它们具有正确的信息,或者B)在加载数据后更改以反映正确的信息Javascript 如何在启动时使用异步存储数据呈现React本机组件?,javascript,android,reactjs,asynchronous,react-native,Javascript,Android,Reactjs,Asynchronous,React Native,我想从AsyncStorage加载并在react本机组件呈现期间使用它,但我的组件在应用程序启动时立即呈现,并且没有给AsyncStorage返回数据的时间 如何使用AsyncStorage使我的组件可以A)等待呈现,直到它们具有正确的信息,或者B)在加载数据后更改以反映正确的信息 import React from 'react'; import { AsyncStorage } from 'react-native'; // my wrapper object ar
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}来自'React';
从“react native”导入{AppRegistry,StyleSheet,Alert};
从“本机基”导入{容器、标题、内容、正文、列表、文本};
从“react native easy Grid”导入{Col,Row,Grid};
从“../../components/AchievementCard/AchievementCard”导入AchievementCard
导出默认类AchieventScreen扩展组件{
建造师(道具){
超级(道具);
//调试器显示props.storageManager形状良好但为空。
此.state={
storageManager:this.props.storageManager,
achievementCards:[this.MoneySavedHievement(props.storageManager),
{标题:“标题2”,正文:“正文2”,图标:“货币”},
]
}
}
MoneySavedHievement(存储管理器){
返回{
标题:“省钱”,
正文:storageManager.data.settings.currency+
storageManager.data.settings.costPerDay*
storageManager.data.settings.days,
图标:“金钱”
}
}
render(){
返回(
}
/>
}
/>
);
}
}
AppRegistry.registerComponent('AchieventScreen',()=>AchieventScreen);
我的frontpage应用程序代码
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);
import React,{Component}来自'React';
从“react native”导入{AppRegistry,StyleSheet};
从“本机基础”导入{Tabs,Tab,Container,Header,Title,Body,TabHeading,Text,Right,Left,Button,TouchableOpacity};
从“反应本机矢量图标/FontAwesome”导入图标;
从“./app/screens/HomeScreen/HomeScreen”导入主屏幕;
从“/app/screens/MilestoneScreen/MilestoneScreen”导入MilestoneScreen;
从“/app/screens/AchieventScreen/AchieventScreen”导入AchieventScreen;
从“/app/modules/StorageManager/StorageManager”导入StorageManager;
导出默认类my_react_应用程序扩展组件{
构造函数(){
超级();
此.state={
storageManager:new storageManager()
}
}
render(){
返回(
我的应用程序
);
}
}
AppRegistry.registerComponent('my_react_app',()=>my_react_app');
我看到的一个紧迫问题是,实现屏幕
组件依赖于storageManager,因此该组件可以重新渲染(从外部效果)的唯一方法是如果storageManager
属性发生更改,而这不会发生
这条线-
<AchievementScreen storageManager={this.state.storageManager} />
希望这有帮助 如您在问题中所述,在storageManager检索到数据之前,您的AcquisitionScreen组件已呈现。实际上,您正在构造函数中显式设置状态:
this.state={storageManager:this.props.storageManager}
这将设置This.state.storageManager
的值,当storageManager更新了数据时,AchieventScreen组件不知道如何处理它
您可以在组件中添加一个组件WillReceiveProps
生命周期挂钩,该挂钩将在组件每次收到新道具时调用。因此,你可以:
在AchieventScreen中-构造函数下:
componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps) {