Flutter: почему setState (() {}) снова и снова устанавливает данные - PullRequest
2 голосов
/ 11 июля 2020

Я использую setState(() {}) для присвоения значения переменной. Но он печатается снова и снова. Почему он так реагирует? И как я могу это исправить?

Вот мой код:

class Sample extends StatefulWidget {
  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {
  String _message;
  String _appLink;
  Firestore db = Firestore.instance;
  @override
  Widget build(BuildContext context) {
    db.collection('share').document('0').get().then((value) {
      var message = value.data['message'];
      print(message);
      var appLink = value.data['appLink'];
      setState(() {
        _message = message;
        _appLink = appLink;
      });
    });
    return Container(
      child: Text('$_message $_appLink'),
    );
  }
}

Вот мой результат:

Здесь _appLink значение www.facebook.com

введите описание изображения здесь

1 Ответ

5 голосов
/ 11 июля 2020

Цель setState - сообщить фреймворку, что переменная в состоянии изменилась и виджет необходимо перестроить, чтобы отразить это изменение. Таким образом, вызов setState снова вызывает функцию build, которая в вашем случае напоминает ваш Future, который снова вызывает setState, что запускает build и т. Д.

Чтобы исправить это, вы должны вызовите Future в initState и используйте FutureBuilder для отображения данных, когда они будут готовы.

Пример:

class _SampleState extends State<Sample> {
  Firestore db = Firestore.instance;
  Future databaseFuture;

  @override
  void initState() {
    databaseFuture = db.collection('share').document('0').get()
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: databaseFuture,
      builder: (context, snapshot) {
        if(!snapshot.hasData) {
          return CircularProgressIndicator();
        }
        var message = snapshot.data.data['message'];
        print(message);
        var appLink = snapshot.data.data['appLink'];
        return Text('$message $appLink');
      }
    ),
  }
}
...