Javascript 如何在启动时使用异步存储数据呈现React本机组件?

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

我想从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}来自'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) {