Статья Flutter Web в 2025: Готов к продакшену? будет добавлена позже.
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это подход к разработке приложений, который делает код масштабируемым, тестируемым и легко поддерживаемым. В этом руководстве разберём как применять Clean Architecture во Flutter проектах в 2025 году.
Что такое Clean Architecture?
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это подход к разработке приложений, который делает код масштабируемым, тестируемым и легко поддерживаемым. В этом руководстве разберём как применять Clean Architecture во Flutter проектах в 2025 году.
Что такое Clean Architecture?
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это подход к разработке приложений, который делает код масштабируемым, тестируемым и легко поддерживаемым. В этом руководстве разберём как применять Clean Architecture во Flutter проектах в 2025 году.
Что такое Clean Architecture?
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это подход к разработке приложений, который делает код масштабируемым, тестируемым и легко поддерживаемым. В этом руководстве разберём как применять Clean Architecture во Flutter проектах в 2025 году.
Что такое Clean Architecture?
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Clean Architecture — это подход к разработке приложений, который делает код масштабируемым, тестируемым и легко поддерживаемым. В этом руководстве разберём как применять Clean Architecture во Flutter проектах в 2025 году.
Что такое Clean Architecture?
Clean Architecture — это концепция, предложенная Robert C. Martin (Uncle Bob), которая разделяет приложение на слои с чёткими обязанностями. Основная идея — зависимости направлены внутрь, а внешние слои ничего не знают о внутренних.
Ключевые принципы:
- Независимость от фреймворков — бизнес-логика не зависит от Flutter
- Тестируемость — каждый слой тестируется отдельно
- Независимость от UI — бизнес-логика работает без виджетов
- Независимость от базы данных — можно легко заменить источник данных
- Внешние зависимости идут внутрь — внутренние слои ничего не знают о внешних
Слои Clean Architecture
Классическая Clean Architecture состоит из трёх основных слоев:
- Domain (Доменный слой) — бизнес-логика, сущности, use cases
- Data (Данный слой) — репозитории, DTO, источники данных
- Presentation (Презентационный слой) — UI, state management
Рассмотрим каждый слой подробно.
Заключение
Clean Architecture во Flutter — это инвестиция в будущее вашего приложения. Да, требуется больше кода и времени на разработку, но код становится легко тестируемым и масштабируемым.
Dart 3.5 принес значительные улучшения в язык, которые делают разработку на Flutter более продуктивной и код более безопасным. В этой статье разберём ключевые нововведения.
Что нового в Dart 3.5?
- Pattern matching — мощная система сопоставления с образцом
- Records — легковесные неизменяемые данные
- Class modifiers — новый контроль над классами
- Улучшенные generics
- Enhanced switch expressions
- И многое другое
Pattern Matching
Pattern matching — это способ деструктуризации и проверки значений:
// Простой pattern
switch (value) {
case int x when x > 0:
print('Positive: $x');
case int x:
print('Non-positive: $x');
case String s:
print('String: $s');
default:
print('Other');
}
// Pattern в переменных
final (name, age) = getUser();
print('$name is $age years old');
// Pattern в циклах
final map = {'a': 1, 'b': 2};
for (final (key, value) in map.entries) {
print('$key: $value');
}
Records
Records — это неизменяемые данные-классы:
// Объявление record
record User(String name, int age) {
String get description => '$name is $age years old';
}
// Использование
final user = User('Alice', 30);
print(user.name); // Alice
print(user.age); // 30
print(user.description); // Alice is 30 years old
// Деструктуризация
final (name, age) = user;
Заключение
Dart 3.5 делает язык более современным и выразительным. Начните использовать новые возможности в своих проектах уже сегодня!
CI/CD (Continuous Integration/Continuous Delivery) автоматизирует процесс сборки, тестирования и публикации Flutter приложений. Codemagic — это специализированный CI/CD сервис для Flutter. В этом руководстве разберём полную настройку.
Что такое Codemagic?
Codemagic — это cloud-based CI/CD платформа, созданная специально для Flutter и React Native.
Преимущества: — Специализируется на Flutter — Простая настройка за 5 минут — Бесплатный план для Open Source — Test distribution — Code signing из коробки — Fastlane integration
Начало работы
Регистрация
- Зарегистрируйтесь на codemagic.io
- Подключите GitHub/GitLab/Bitbucket репозиторий
- Выберите Flutter проект
Первая сборка
Codemagic автоматически определит Flutter проект и предложит конфигурацию:
workflows:
sample-workflow:
name: Codemagic Sample
triggering:
events:
- push
branch_patterns:
- pattern: main
include: false
environment:
vars:
XCODE_WORKSPACE: codemagicFlutter.xcworkspace
XCODE_SCHEME: codemagicFlutter
flutter: stable
scripts:
- name: Build Android app
script: flutter build apk --release
artifacts:
- build/app/outputs/flutter-apk/*.apk
Настройка тестов
Unit тесты
scripts:
- name: Run Flutter tests
script: flutter test
Integration тесты
scripts:
- name: Run integration tests
script: flutter test integration_test --no-sound-null-safety
Code coverage
scripts:
- name: Generate coverage
script: flutter test --coverage
- name: Upload coverage
script: bash <(curl -s https://codecov.io/bash)
Code Signing
Android
scripts:
- name: Set up key properties
script: |
echo $CM_KEYSTORE_PROPERTIES | base64 --decode > keystore.properties
- name: Build release APK
script: |
flutter build apk --release \
--keystore $CM_KEYSTORE \
--store-password $CM_KEYSTORE_PASSWORD \
--key-password $CM_KEY_PASSWORD \
--key-alias $CM_KEY_ALIAS
iOS
scripts:
- name: Set up code signing
script: |
keychain initialize
keychain set-defaults
- name: Fetch signing certificates
script: |
app-store-connect fetch-signing-files \
$CM_BUNDLE_ID \
--platform IOS \
--type IOS_APP_DEVELOPMENT \
--certificate-key $CM_CERTIFICATE_PRIVATE_KEY \
--certificate-issuer $CM_CERTIFICATE_ISSUER
- name: Build IPA
script: flutter build ipa --release --export-options-plist exportOptions.plist
Публикация в сторы
Google Play
scripts:
- name: Upload to Google Play
script: |
cd android
fastlane supply \
--apk build/app/outputs/flutter-apk/app-release.apk \
--track internal \
--json_key_data $CM_SERVICE_ACCOUNT_JSON
App Store
scripts:
- name: Upload to TestFlight
script: |
app-store-connect publish \
--path build/ios/ipa/*.ipa \
--skip_screenshots \
--skip_waiting_for_build_processing
Заключение
Codemagic — отличный выбор для CI/CD Flutter приложений. Начните с простого workflow и усложняйте по мере необходимости.
Riverpod 2.0 — это major update популярной библиотеки управления состоянием для Flutter. В этом руководстве разберём основные концепции, провайдеры и кодогенерацию с примерами.
Что такое Riverpod?
Riverpod (Provider наоборот) — это современная система управления состоянием от Remi Rousselet, автора пакета provider. Это следующая эволюция, которая решает многие ограничения оригинального Provider.
Ключевые преимущества: — Compile-time безопасность — ошибки обнаруживаются при компиляции — Не требует BuildContext — доступ к состоянию из любого места — Auto-dispose — автоматическое освобождение ресурсов — Code generation — типобезопасные провайдеры — Тестирование — простое мокирование зависимостей
Установка
Добавьте зависимости в pubspec.yaml:
dependencies:
flutter_riverpod: ^2.5.0
dev_dependencies:
riverpod_generator: ^2.4.0
riverpod_lint: ^2.3.0
build_runner: ^2.4.0
Основные концепции
Provider
Provider — это источник данных. Он может быть: — Значением (число, строка, объект) — Функцией, которая вычисляет значение — Async-функцией для загрузки данных из API — Stream для real-time данных
// Простой провайдер значения
final counterProvider = Provider<int>((ref) => 42);
// Провайдер с вычислением
final doubleProvider = Provider<int>((ref) {
final value = ref.watch(counterProvider);
return value * 2;
});
StateProvider
StateProvider — для простого изменяемого состояния:
final countProvider = StateProvider<int>((ref) => 0);
// В виджете
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return ElevatedButton(
onPressed: () => ref.read(countProvider.notifier).state++,
child: Text('Count: $count'),
);
}
}
StateNotifierProvider
Для более сложной логики используйте StateNotifier:
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
void decrement() => state--;
void reset() => state = 0;
}
final counterNotifierProvider = StateNotifierProvider<Counter, int>((ref) {
return Counter();
});
AsyncNotifierProvider
Для работы с asynchronous данными (API, базы данных):
@riverpod
class UserRepository extends _$UserRepository {
@override
Future<User> build(String userId) async {
final response = await http.get('/api/users/$userId');
return User.fromJson(jsonDecode(response.body));
}
}
// Использование
class UserWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userRepositoryProvider('123'));
return userAsync.when(
data: (user) => Text(user.name),
loading: () => CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
);
}
}
Code Generation в Riverpod 2.0
Riverpod 2.0 поддерживает кодогенерацию для большей типобезопасности:
// Объявление провайдера с аннотацией
@riverpod
String greeting(GreetingRef ref) {
return 'Hello, World!';
}
// Параметризованный провайдер
@riverpod
Future<User> fetchUser(FetchUserRef ref, int id) async {
final response = await http.get('/api/users/$id');
return User.fromJson(jsonDecode(response.body));
}
// Class-based провайдер с состоянием
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
void decrement() => state--;
}
После добавления аннотации запустите генератор:
flutter pub run build_runner build
Чтение и обновление состояния
ref.watch — подписаться на изменения (в build методе):
final value = ref.watch(myProvider);
ref.read — получить значение без подписки (в callback):
onPressed: () {
final value = ref.read(myProvider);
print(value);
// Или для StateProvider:
ref.read(myProvider.notifier).state++;
}
ref.listen — слушать изменения и реагировать:
ref.listen<int>(countProvider, (previous, next) {
print('Count changed from $previous to $next');
if (next > 10) {
showNotification('Limit reached!');
}
});
ConsumerWidget и ConsumerStatefulWidget
Для использования провайдеров в виджетах:
// Stateless виджет с провайдерами
class MyScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('Count: $count');
}
}
// Stateful виджет
class MyScreen extends ConsumerStatefulWidget {
@override
ConsumerState<MyScreen> createState() => _MyScreenState();
}
class _MyScreenState extends ConsumerState<MyScreen> {
@override
Widget build(BuildContext context) {
final count = ref.watch(countProvider);
return ElevatedButton(
onPressed: () => ref.read(countProvider.notifier).state++,
child: Text('Count: $count'),
);
}
}
ProviderScope и ProviderContainer
Оберните приложение в ProviderScope:
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
Для тестов используйте ProviderContainer:
test('counter increments', () {
final container = ProviderContainer();
// Чтение значения
expect(container.read(countProvider), 0);
// Изменение значения
container.read(countProvider.notifier).state++;
expect(container.read(countProvider), 1);
// Не забудьте удалить контейнер
container.dispose();
});
Модификаторы провайдеров
.family
Параметризованные провайдеры:
final userProvider = FutureProvider.family<User, int>((ref, id) async {
final response = await http.get('/api/users/$id');
return User.fromJson(jsonDecode(response.body));
});
// Использование
final userAsync = ref.watch(userProvider(123));
.autoDispose
Автоматическое освобождение ресурсов когда никто не слушает:
final socketProvider = StreamProvider.autoDispose<WebSocket>((ref) {
final socket = WebSocket.connect('ws://example.com');
ref.onDispose(() => socket.close());
return socket;
});
Полный пример приложения
Создадим простое ToDo приложение:
// Модель задачи
class Todo {
final String id;
final String title;
final bool completed;
Todo({required this.id, required this.title, this.completed = false});
Todo copyWith({String? title, bool? completed}) {
return Todo(
id: id,
title: title ?? this.title,
completed: completed ?? this.completed,
);
}
}
// Провайдер списка задач
@riverpod
class TodoList extends _$TodoList {
@override
List<Todo> build() {
return [];
}
void add(String title) {
state = [...state, Todo(id: DateTime.now().toString(), title: title)];
}
void toggle(String id) {
state = [
for (final todo in state)
if (todo.id == id) todo.copyWith(completed: !todo.completed) else todo
];
}
void remove(String id) {
state = state.where((todo) => todo.id != id).toList();
}
}
// UI
class TodoApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final todos = ref.watch(todoListProvider);
return Scaffold(
appBar: AppBar(title: Text('Todo Riverpod')),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
leading: Checkbox(
value: todo.completed,
onChanged: (_) => ref.read(todoListProvider.notifier).toggle(todo.id),
),
title: Text(todo.title),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => ref.read(todoListProvider.notifier).remove(todo.id),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => _showAddDialog(context, ref),
child: Icon(Icons.add),
),
);
}
}
Тестирование
Riverpod упрощает тестирование:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('adds todo', () {
final container = ProviderContainer();
// Добавляем задачу
container.read(todoListProvider.notifier).add('Test task');
// Проверяем
expect(container.read(todoListProvider).length, 1);
expect(container.read(todoListProvider).first.title, 'Test task');
container.dispose();
});
testWidgets('toggles todo', (tester) async {
await tester.pumpWidget(
ProviderScope(
child: MaterialApp(home: TodoApp()),
),
);
// Добавляем задачу через UI
await tester.tap(find.byType(FloatingActionButton));
await tester.enterText(find.byType(TextField), 'New task');
await tester.tap(find.text('Add'));
await tester.pump();
// Переключаем
await tester.tap(find.byType(Checkbox));
await tester.pump();
// Проверяем
expect(find.text('New task'), findsOneWidget);
});
}
Лучшие практики
- Используйте code generation для большей типобезопасности
- Разделяйте провайдеры по файлам по domain
- Применяйте autoDispose для ресурсов которые нужно освобождать
- Тестируйте провайдеры изолированно от UI
- Используйте family для параметризованных данных
- Избегайте watch в методах кроме build (используйте read)
Заключение
Riverpod 2.0 — это мощная и типобезопасная система управления состоянием для Flutter. Кодогенерация делает код чище, а compile-time проверки помогают избегать runtime ошибок.
Начните с простого: — Для простых счетчиков используйте StateProvider — Для сложной логики — StateNotifier или @riverpod class — Для API запросов — FutureProvider или AsyncNotifierProvider — Для streams — StreamProvider
Документация: https://riverpod.dev