Ответ
Мой топ-3 библиотек для production-разработки на Flutter:
-
Riverpod (замена Provider) – Современный state-менеджмент и dependency injection.
- Почему: Решает проблемы Provider (например, с
context), имеет отличную поддержку типов, тестируемость и не зависит от дерева виджетов.final counterProvider = StateProvider<int>((ref) => 0);
class MyWidget extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return Text('Count: $count'); } }
- Почему: Решает проблемы Provider (например, с
-
Dio – HTTP-клиент.
- Почему: Превосходит стандартный
httpпакет благодаря interceptors (для логирования, добавления токенов), поддержке отмены запросов,FormData, и встроенным трансформаторам ответов.final dio = Dio(); dio.interceptors.add(LogInterceptor()); final response = await dio.get<Map<String, dynamic>>('/user/1'); final user = User.fromJson(response.data!);
- Почему: Превосходит стандартный
-
GoRouter (или AutoRoute) – Навигация.
- Почему: Объявляемая маршрутизация с type-safe передачей аргументов. Гораздо чище и надежнее, чем
Navigator.pushNamedсargumentsтипаMap<String, dynamic>.GoRoute( path: '/user/:id', builder: (context, state) { final userId = state.pathParameters['id']!; // Тип - String return UserProfilePage(userId: userId); }, );
- Почему: Объявляемая маршрутизация с type-safe передачей аргументов. Гораздо чище и надежнее, чем
Ответ 18+ 🔞
А, ну это же просто праздник какой-то! Сидишь, значит, пишешь на Flutter, и тут бац — понимаешь, что без правильных библиотек ты как без рук, а руки, блядь, из жопы растут. Слушай сюда, я тебе сейчас свой священный топ-тройку вывалю, на чём всё держится в продакшене. Без этой троицы — это не разработка, а мартышлюшка с гранатой, честно.
На первом месте, ёпта, Riverpod. Это не просто замена тому старому Provider, который уже всем бздеть надоел. Это, блядь, как пересесть с запряжённой лошади на реактивный самолёт. Все эти проблемы с context, когда ты его ищешь, а он нихуя не находится, или дерево виджетов тебя подставляет — всё, забыл. Типы — огонь, тестировать — одно удовольствие, и от виджетов не зависишь. Просто смотри, как элегантно всё становится:
final counterProvider = StateProvider<int>((ref) => 0);
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Text('Count: $count');
}
}
Видишь? Никакого лишнего геморроя. Чисто, типобезопасно, и доверия к этому решению — овердохуища.
Дальше, второй обязательный кирпич в фундаменте — Dio. Стандартный http пакет — это, извини, как ехать на велике через всю страну, когда есть машина. Dio — это та самая машина, да ещё и с турбонаддувом. Interceptors, блядь! Это же магия! Хочешь логировать все запросы-ответы? Пожалуйста. Автоматом токен авторизации цеплять? Да легко! Отмену запросов, работу с FormData — всё из коробки. Смотри, как просто жизнь налаживается:
final dio = Dio();
dio.interceptors.add(LogInterceptor());
final response = await dio.get<Map<String, dynamic>>('/user/1');
final user = User.fromJson(response.data!);
После такого на стандартный пакет даже смотреть не хочется, честное слово. Чувствуешь разницу? Я — да.
Ну и третий столп, без которого просто пиздец, а не навигация — GoRouter (или AutoRoute, кому что ближе). Нативный Navigator.pushNamed с его arguments в виде Map<String, dynamic> — это просто привет из 2002 года, ядрёна вошь. Типобезопасность на нуле, опечатки в ключах — обычное дело, в общем, волнение ебать каждую секунду. А тут — объявляешь маршруты, и всё. Аргументы передаются не как попало, а как должно.
GoRoute(
path: '/user/:id',
builder: (context, state) {
final userId = state.pathParameters['id']!; // Тип - String, а не "ой, а что там?"
return UserProfilePage(userId: userId);
},
);
Красота же! Никаких сюрпризов, никакого «а почему у меня тут null?». Всё строго, чётко, надёжно. Без этой троицы лезть в production — это чистой воды распиздяйство, имей в виду.