FLUTTER: Двойное пересоздание виджет StateFull -> Build
Как (можно ли) устранить двойное создание виджета Widget build(BuildContext context)?
Классическая структура есть класс от StatefullWidget
class BodyView extends StatefulWidget {
@override
_BodyViewState createState() => _BodyViewState();
}
И есть тело в котором переопределен initState (Добавленна загрузка _loadSelect() из SharedPreferences значения selectPage с setState()-ом)
class _BodyViewState extends State<BodyView> {
int selectedPage;
@override
void initState() {
super.initState();
_loadSelect();
}
@override
Widget build(BuildContext context) {
Получается что Widget создается до выполнения метода initState(и пытается вывести себя на экран, при этом значение selectedPage не определено). После чего выполняется initState и еще раз запускает пересоздание Widget-а.
Пробовал через Future сделать - аналогичная ситуация. Что я не правильно делаю? Или как правильно. Или это проблема Flutter-а и её не исправить?
Ответы (1 шт):
Или это проблема Flutter-а и её не исправить?
В первую очередь это не понимание как работает Flutter. Для начала я рекомендую прочитать про разницу между StatlessWidget и StatefulWidget, а также как работает асинхронность в Flutter.
Ответ на ваш изначальный вопрос:
В initState вы запускаете асинхронную функцию (то есть не блокируете дальнейшие построение widget, что является правильным), далее widget строиться, но без значения selectedPage (что скорее всего и дает ошибку). После чего _loadSelect завершает свою работу и вызывает setState, тем самым вызывая перестроение widget уже во второй раз.
Чтобы не перестраивать весь widget можно использовать FutureBuilder, он будет сам следить и вызывать перестроение внутри себя когда асинхронная операция будет завершаться. Но это не освобождает вас от того, что на момент когда асинхронная операция выполняется вам нужно что-то показать пользователю (лоадер и т.д.).
Либо использовать State Management: Redux, BLoC, MobX...
Widget никогда не создается до выполнения метода initState