Подтвердить что ты не робот

React Native AsyncStorage извлекает данные после рендеринга

Я использую AsyncStorage в ComponentWillMount для локального сохранения accessToken, но он возвращает обещание после выполнения функции render(). Как я могу сделать render() до тех пор, пока не будет выполнено обещание? Спасибо.

4b9b3361

Ответ 1

Вы не можете сделать render ждать, насколько я знаю. То, что я сделал в приложении, над которым я работаю, - это добавить экран загрузки, пока это обещание от AsyncStorage не будет устранено. См. Пример ниже:

import React, {
  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/>;
  }

}

Установка свойства isLoading в объекте состояния приведет к повторной визуализации, а затем вы можете показать содержимое, основанное на accessToken.

На стороне примечания я написал небольшую библиотеку под названием react-native-simple-store, которая упрощает управление данными в AsyncStorage. Надеюсь, вы сочтете это полезным.

Ответ 2

На основе реакции-native doc вы можете сделать что-то вроде этого:

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

Ответ 3

React-native основан на Javascript, который не поддерживает блокирующие функции. Также это имеет смысл, поскольку мы не хотим, чтобы пользовательский интерфейс застревал или казался невосприимчивым. Что вы можете сделать, это обрабатывать это в функции рендеринга. У меня есть экран загрузки, повторно отображающий его, как вы, когда вы получаете информацию из AsyncStorage