gpt4 book ai didi

javascript - 如何在启动时使用异步存储数据渲染 React Native 组件?

转载 作者:行者123 更新时间:2023-11-29 23:24:40 26 4
gpt4 key购买 nike

我想从 AsyncStorage 加载并在我的 React native 组件渲染期间使用它,但我的组件在应用程序启动时立即渲染并且没有给 AsyncStorage 返回数据的时间。

我如何使用 AsyncStorage 以便我的组件要么 A) 等待呈现直到它们具有正确的信息,要么 B) 在数据加载后更改以反射(reflect)正确的信息?

    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);

最佳答案

我看到的一个直接问题是 AchievementScreen 组件依赖于 storageManager,因此组件可以重新渲染(从外部效果)的唯一方法是 storageManager prop 更改,但不会发生。

这一行-

<AchievementScreen storageManager={this.state.storageManager} />

此外,如果您希望 AchievementScreen 在数据获取时重新呈现,更好的设计是将数据传递给 AchievementScreen 而不是传递一个对象获取数据。 AchievementScreen 应该不知道数据是从哪里获取的。 (为了更好地管理副作用,请查看 redux、redux-thunk、redux-saga 等库)

所以您的理想实现方式是 -

componentDidMount(){
this.storageManager.getData().then((data) =>
this.setState({moneySavedAchievement: data});
);
}

<AchievementScreen moneySavedAchievement={moneySavedAchievement} />

希望对您有所帮助!

关于javascript - 如何在启动时使用异步存储数据渲染 React Native 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49664694/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com