【问题标题】:How to get async data without reloading whole app如何在不重新加载整个应用程序的情况下获取异步数据
【发布时间】:2019-02-19 10:54:46
【问题描述】:

我正在尝试当用户单击bottomTabNavigator 时组件屏幕将重新加载。我的意思是在我的第一个组件屏幕“AnotherA.js”中,我使用 textinput 将用户输入的数据存储在异步存储中,而在另一个组件“AnotherB.js”中,我使用异步存储的 get() 来显示我存储的数据屏幕。我能够在重新加载整个应用程序时第一次看到存储的数据。

我正在尝试在不重新加载整个应用程序的情况下获取数据,方法是使用bottomTabNavigator 导航,它会立即显示。

//App.js

import React, { Component } from "react";
import { createAppContainer } from 'react-navigation';
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';
import { TabNavigator } from 'react-navigation';
import AnotherA from './AnotherA';
import AnotherB from './AnotherB';

const AppNavigator = createMaterialBottomTabNavigator(
  {
    AnotherA: { screen: AnotherA },
    AnotherB: { screen: AnotherB }
  },
  {
    initialRouteName: 'AnotherA',
    activeColor: '#f0edf6',
    inactiveColor: '#3e2465',
    barStyle: { backgroundColor: '#694fad' },
    pressColor: 'pink',
  },
  {
    //tabBarComponent: createMaterialBottomTabNavigator /* or TabBarTop */,
    tabBarPosition: 'bottom',
    defaultnavigationOptions: ({ navigation }) => ({
      tabBarOnPress: (scene, jumpToIndex) => {
        console.log('onPress:', scene.route);
        jumpToIndex(scene.index);

      },
    }),

  }
);
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;

//另一个A.js

import React, { Component } from 'react';
import { AppRegistry, AsyncStorage, View, Text, Button, TextInput, StyleSheet, Image, TouchableHighlight, Linking } from 'react-native';
import styles from './styles';

export default class AnotherA extends Component {
    constructor(props) {
        super(props);
        this.state = {
            myKey: '',
            text1: '',

        }
    }

    async getKey() {
        try {
            //const value = await AsyncStorage.getItem('@MySuperStore:key');
            const key = await AsyncStorage.getItem('@MySuperStore:key');

            this.setState({
                myKey: key,
            });
        } catch (error) {
            console.log("Error retrieving data" + error);
        }
    }

    async saveKey(text1) {
        try {
            await AsyncStorage.setItem('@MySuperStore:key', text1);
        } catch (error) {
            console.log("Error saving data" + error);
        }
    }

    async resetKey() {
        try {
            await AsyncStorage.removeItem('@MySuperStore:key');
            const value = await AsyncStorage.getItem('@MySuperStore:key');
            this.setState({
                myKey: value,
            });
        } catch (error) {
            console.log("Error resetting data" + error);
        }
    }

    componentDidMount() {
        this.getKey();
    }

    render() {
        return (
            <View style={styles.container}>
                <TextInput
                    placeholder="Enter Data"
                    value={this.state.myKey}
                    onChangeText={(value) => this.setState({ text1: value })}
                    multiline={true}
                />
                <Button
                    onPress={() => this.saveKey(this.state.text1)}
                    title="Save"
                />
                <Button
                    //style={styles.formButton}
                    onPress={this.resetKey.bind(this)}
                    title="Reset"
                    color="#f44336"
                    accessibilityLabel="Reset"
                />
                </View>
        )
    }
}

//另一个B.js

import React, { Component } from 'react';
import { AppRegistry, AsyncStorage, View, Text, Button, TextInput, StyleSheet, Image, TouchableHighlight, Linking } from 'react-native';
import styles from './styles';

export default class AnotherB extends Component {
    constructor(props) {
        super(props);
        this.state = {
            myKey: '',
            text1: '',

        }
    }

    async getKey() {
        try {
            //const value = await AsyncStorage.getItem('@MySuperStore:key');
            const key = await AsyncStorage.getItem('@MySuperStore:key');

            this.setState({
                myKey: key,
            });
        } catch (error) {
            console.log("Error retrieving data" + error);
        }
    }

    componentDidMount() {
        this.getKey();
    }

    render() {
        //const { navigate } = this.props.navigation;
        //const { newValue, height } = this.state;
        return (
            <View style={styles.container}>
                <Text>{this.state.myKey}</Text>
            </View>
        )
    }
}

请建议,我是 React-Native 的新手。

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    问题是当组件挂载时您正在从AsyncStorage 检索值。不幸的是,当您切换标签时,这不会在屏幕上加载值。您需要做的是订阅updates 以导航生命周期。

    这是相当直截了当的。您可以订阅四个生命周期事件。您可以选择要订阅的内容。

    • willFocus - 屏幕将聚焦
    • didFocus - 屏幕聚焦(如果有过渡,则过渡完成)
    • willBlur - 屏幕将失焦
    • didBlur - 屏幕失焦(如果有过渡,则过渡完成)

    您在组件挂载时订阅事件,然后在组件卸载时取消订阅。所以当你订阅的事件发生时,它会调用你放入订阅者回调的函数。

    所以你可以在你身上做这样的事情AnotherB.js

    componentDidMount() {
        // subscribe to the event that we want, in this case 'willFocus'
        // when the screen is about to focus it will call this.getKey
        this.willFocusSubscription = this.props.navigation.addListener('willFocus', this.getKey);
    }
    
    componentWillUnmount() {
        // unsubscribe to the event 
        this.willFocusSubscription.remove();
    }
    
    getKey = async () => { // update this to an arrow function so that we can still access this, otherwise we'll get an error trying to setState.
        try {
            const key = await AsyncStorage.getItem('@MySuperStore:key');
            this.setState({
                myKey: key,
            });
        } catch (error) {
            console.log("Error retrieving data" + error);
        }
    }
    

    这是我创建的快餐,显示它的工作原理,https://snack.expo.io/@andypandy/navigation-life-cycle-with-asyncstorage

    【讨论】:

      【解决方案2】:

      你可以尝试在getItem之后添加then

      AsyncStorage.getItem("@MySuperStore:key").then((value) => {
          this.setState({
              myKey: value,
          });
      })
      .then(res => {
          //do something else
      });
      

      【讨论】:

      • 对不起!但什么也没发生。
      • 把上面的代码放到AnotherB.js的componentDidMount()中
      猜你喜欢
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多