Как вызвать асинхронный метод в методе рендеринга с Expo?

#react-native #expo

Вопрос:

Я сохранил данные в AsyncStorage. Теперь я хочу показать все данные из AsyncStorage на отдельном экране. Метод getData является асинхронным методом. Он считывается из хранилища AsyncStorage. Я использую такой код

 import React from "react";

class List extends React.Component {
  state = { list: null };

  async componentDidMount() {
    const list = await getData("List");
    console.log('LIST: '   JSON.stringify(list));
    this.setState({ list });
  }

  render() {
    const { list } = this.state;
    console.log('state: '   JSON.stringify(list));

    if(list || list.length <= 0)
         return (<View><Text>Empty.</Text></View>);

    return (
                <View>
                    { list.map(item => (
                        <Text tabLabel={item}>{item}</Text>
                    ))}
                </View>
        );
   }
} 

Когда я запускаю этот код, я получаю 2 сообщения консоли:
состояние: []
и
СПИСОК: [{item1}, {item2}…]

Это означает, что componentDidMount срабатывает после метода рендеринга, поэтому пользовательский интерфейс пуст.

Как я могу это изменить? Мне нужно прочитать данные из AsyncStorage и показать их в пользовательском интерфейсе.

Спасибо.

Ответ №1:

componentDidMount как говорится в названии, он предназначен для запуска после рендеринга. Для достижения того, что вы хотите сделать, вы можете использовать componentWillMount .

 import React from 'react';

class List extends React.Component {
  state = { list: null };

  componentWillMount() {
    const loadData = async () => {
      const list = await getData('List');
      console.log('LIST: '   JSON.stringify(list));
      this.setState({ list });
    };

    loadData();
  }

  render() {
    const { list } = this.state;
    console.log('state: '   JSON.stringify(list));

    if (list || list.length <= 0)
      return (
        <View>
          <Text>Empty.</Text>
        </View>
      );

    return (
      <View>
        {list.map((item) => (
          <Text tabLabel={item}>{item}</Text>
        ))}
      </View>
    );
  }
}
 

Комментарии:

1. спасибо за идею, но, к сожалению, она имеет тот же эффект.

2. Отредактированное сообщение, посмотрите сейчас

3. Вы изменили componentDidMount на componentWillMount. Спасибо, я постараюсь.

4. Да, именно это я и сделал