React Native AsyncStorage fetches data after rendering

后端 未结 4 1823
一整个雨季
一整个雨季 2020-12-13 04:11

I am using AsyncStorage in ComponentWillMount to get locally stored accessToken, but it is returning the promise after render()<

相关标签:
4条回答
  • 2020-12-13 04:30

    Based on react-native doc, you can do something like this:

    import React, { Component } from 'react';
    import {
      View,
    } from 'react-native';
    
    let STORAGE_KEY = '@AsyncStorageExample:key';
    
    export default class MyApp extends Component {
    
      constructor(props) {
        super(props);
        this.state = {
          loaded: 'false',
        };
      }
    
      _setValue = async () => {
        try {
          await AsyncStorage.setItem(STORAGE_KEY, 'true');
        } catch (error) { // log the error
        }
      };
    
      _loadInitialState = async () => {
        try {
          let value = await AsyncStorage.getItem(STORAGE_KEY);
          if (value === 'true'){
            this.setState({loaded: 'true'});
          } else {
            this.setState({loaded: 'false'});
            this._setValue();
          }
        } catch (error) {
          this.setState({loaded: 'false'});
          this._setValue();
        }
      };
    
      componentWillMount() {
        this._loadInitialState().done();
      }
    
      render() {
        if (this.state.loaded === 'false') {
          return (
            <View><Text>Loading...</Text></View>
          );
        }
        return (
          <View><Text>Main Page</Text></View>
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-13 04:31

    React-native is based on Javascript which does not support blocking functions.Also this makes sense as we don't want the UI to get stuck or seem unresponsive. What you can do is handles this in the render function. i.e Have a loading screen re-render it as you as you get the info from the AsyncStorage

    0 讨论(0)
  • 2020-12-13 04:37

    You can't make a component wait to render, as far as I know. What I've done in the app I'm working on is to add a loading screen until that promise from AsyncStorage resolves. See the examples below:

    //
    // With class component syntax
    //
    
    import React from 'react';
    import {
      AsyncStorage,
      View,
      Text
    } from 'react-native';
    
    class Screen extends React.Component {
    
      state = {
        isLoading: true
      };
    
      componentDidMount() {
        AsyncStorage.getItem('accessToken').then((token) => {
          this.setState({
            isLoading: false
          });
        });
      },
    
      render() {
        if (this.state.isLoading) {
          return <View><Text>Loading...</Text></View>;
        }
        // this is the content you want to show after the promise has resolved
        return <View/>;
      }
    
    }
    
    //
    // With function component syntax and hooks (preferred)
    //
    
    import React, { useEffect } from 'react';
    import {
      AsyncStorage,
      View,
      Text
    } from 'react-native';
    
    const Screen () => {
    
      const [isLoading, setIsLoading] = useState(true);
    
      useEffect(() => {
        AsyncStorage.getItem('accessToken').then((token) => {
          setIsLoading(false);
        });
      }, [])
    
      if (isLoading) {
        return <View><Text>Loading...</Text></View>;
      }
      // this is the content you want to show after the promise has resolved
      return <View/>;
    
    }
    

    Setting the isLoading property in state will cause a re-render and then you can show the content that relies on the accessToken.

    On a side note, I've written a little library called react-native-simple-store that simplifies managing data in AsyncStorage. Hope you find it useful.

    0 讨论(0)
  • 2020-12-13 04:43

    you can use react-native-easy-app that is easier to use than async storage. this library is great that uses async storage to save data asynchronously and uses memory to load and save data instantly synchronously, so we save data async to memory and use in app sync, so this is great.

    import { XStorage } from 'react-native-easy-app';
    import { AsyncStorage } from 'react-native';
    
    const initCallback = () => {
    
         // From now on, you can write or read the variables in RNStorage synchronously
    
         // equal to [console.log(await AsyncStorage.getItem('isShow'))]
         console.log(RNStorage.isShow); 
    
         // equal to [ await AsyncStorage.setItem('token',TOKEN1343DN23IDD3PJ2DBF3==') ]
         RNStorage.token = 'TOKEN1343DN23IDD3PJ2DBF3=='; 
    
         // equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify({ name:'rufeng', age:30})) ]
         RNStorage.userInfo = {name: 'rufeng', age: 30}; 
    };
    
    XStorage.initStorage(RNStorage, AsyncStorage, initCallback); 
    
    0 讨论(0)
提交回复
热议问题