Что такое FutureBuilder

Ответ

FutureBuilder — это виджет Flutter, который упрощает работу с асинхронными операциями (Future). Он автоматически перестраивает интерфейс в зависимости от состояния Future: загрузка, ошибка или успешное завершение.

Основные параметры:

  • future: Future, данные которого нужно отобразить.
  • builder: Функция, возвращающая виджет на основе AsyncSnapshot (содержит данные, ошибку и состояние).

Пример:

FutureBuilder<String>(
  future: fetchData(), // Ваш Future
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    } else if (snapshot.hasError) {
      return Text('Ошибка: ${snapshot.error}');
    } else {
      return Text('Данные: ${snapshot.data}');
    }
  },
)

Особенности:

  • Не кэширует данные — при каждом обновлении родительского виджета Future выполняется заново (если не переиспользовать Future вне FutureBuilder).
  • AsyncSnapshot содержит полезные поля: data, error, connectionState (например, ConnectionState.done).

Используется для простых сценариев. Для сложных состояний (кэширование, повторы) лучше подходят StreamBuilder или пакеты типа flutter_bloc.

Ответ 18+ 🔞

Давай разберём эту штуку, которая называется FutureBuilder. Представь, что ты заказал пиццу, а этот виджет — это курьер, который тебе звонит и говорит: «Я еду», «Я приехал» или «Бля, я с пиццей упал в лужу». В общем, он упрощает всю эту возню с асинхронщиной, когда ты ждёшь данные из сети, базы или просто откуда-то издалека.

Что у него внутри, эта хитрая жопа:

  • future: Это и есть твоя пицца, то есть сам Future, который ты ждёшь. Может быть запрос в API, чтение файла — что угодно.
  • builder: Это твой личный диспетчер. Он получает AsyncSnapshot — сводку от курьера — и решает, что показывать: индикатор загрузки, ошибку или, наконец, горячие данные.

Смотри, как это выглядит в коде:

FutureBuilder<String>(
  future: fetchData(), // Тут твой Future, который что-то тащит
  builder: (context, snapshot) {
    // Ждём пиццу
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator(); // Крутилка, типа "еду уже"
    // Курьер упал
    } else if (snapshot.hasError) {
      return Text('Ошибка: ${snapshot.error}'); // "Пицца на асфальте, прости"
    // Всё, пицца в руках!
    } else {
      return Text('Данные: ${snapshot.data}'); // Ура, жри!
    }
  },
)

Но есть важный нюанс, ёпта!

Он не кэширует данные. Это как если бы при каждом чихе твоего родительского виджета ты заказывал пиццу заново. Овердохуища неэффективно, если future не вынесен наружу и не переиспользуется. AsyncSnapshot даёт тебе всё, что нужно: data, error и состояние connectionState (типа done — всё, приплыли).

Итог: Штука годная для простых случаев — принёс/не принёс. Но если у тебя там сложная логика с повторами, кэшем и прочей магией — это пиздопроебибна. Лучше смотреть в сторону StreamBuilder или тех же state-менеджментов вроде flutter_bloc. А этот пусть работает на быстрых развозках.