Используем flutter_riverpod 2.0 для state management.

  • 25 сентября 2024
  • 27 просмотров
  • 0 комментариев

Для внедрения flutter_riverpod 2.0 для управления состоянием в проекте на Flutter с использованием clean architecture, выполните следующие шаги:

1. Установка зависимостей

В pubspec.yaml добавьте зависимость flutter_riverpod:

dependencies:
  flutter_riverpod: ^2.0.0  # Проверьте последнюю версию

Запустите команду flutter pub get, чтобы установить зависимости.

2. Структура проекта с чистой архитектурой

Ваш проект должен следовать принципам чистой архитектуры с такой структурой:

  • domain: содержит сущности, юзкейсы и интерфейсы репозиториев.
  • data: реализует репозитории, API-клиенты и другие источники данных.
  • presentation: содержит UI-код, view models и логику управления состоянием.

3. Настройка провайдеров для юзкейсов и репозиториев

Шаг 1: Репозиторий

Создайте репозиторий для получения данных, который будет использоваться в слое domain:

class UserRepository {
  Future<User> getUserData() async {
    // Логика для получения данных пользователя (например, из API или локальной базы данных)
    return User(name: "John Doe", age: 30);
  }
}

final userRepositoryProvider = Provider<UserRepository>((ref) {
  return UserRepository();
});

Шаг 2: Юзкейс

Юзкейсы содержат бизнес-логику и взаимодействуют с репозиториями:

class GetUserDataUseCase {
  final UserRepository repository;

  GetUserDataUseCase(this.repository);

  Future<User> call() async {
    return await repository.getUserData();
  }
}

final getUserDataUseCaseProvider = Provider<GetUserDataUseCase>((ref) {
  final repository = ref.watch(userRepositoryProvider);
  return GetUserDataUseCase(repository);
});

4. Управление состоянием с помощью Notifier

Используйте Notifier для управления состоянием, чтобы упростить логику.

class UserNotifier extends Notifier<User?> {
  final GetUserDataUseCase getUserDataUseCase;

  UserNotifier(this.getUserDataUseCase);

  @override
  User? build() {
    return null; // Начальное состояние: нет данных
  }

  Future<void> loadUser() async {
    state = await getUserDataUseCase(); // Получение данных и обновление состояния
  }

  void clearUser() {
    state = null; // Очистка состояния
  }
}

final userNotifierProvider = NotifierProvider<UserNotifier, User?>((ref) {
  final getUserDataUseCase = ref.watch(getUserDataUseCaseProvider);
  return UserNotifier(getUserDataUseCase);
});

5. Использование провайдеров в UI

Использование Notifier в UI

class UserScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(userNotifierProvider);

    return Scaffold(
      appBar: AppBar(
        title: Text('User Info'),
      ),
      body: Center(
        child: user == null
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('No user loaded'),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      ref.read(userNotifierProvider.notifier).loadUser();
                    },
                    child: Text('Load User'),
                  ),
                ],
              )
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('Name: ${user.name}, Age: ${user.age}'),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      ref.read(userNotifierProvider.notifier).clearUser();
                    },
                    child: Text('Clear User'),
                  ),
                ],
              ),
      ),
    );
  }
}

6. Оберните ваше приложение в ProviderScope

В файле main.dart оберните приложение с помощью ProviderScope:

void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UserScreen(),
    );
  }
}

Заключение:

  1. ProviderScope: Необходим для включения управления состоянием с помощью Riverpod во всем приложении.
  2. Notifier: Управляет изменениями состояния более просто и удобно по сравнению с StateNotifier (использовался в более старых версиях flutter_riverpod), что подходит для более простых сценариев.
  3. Разделение ответственности: В соответствии с чистой архитектурой, репозиторий и юзкейсы отделены от UI, что делает код более поддерживаемым и тестируемым.

Посмотреть подходящие вакансии для Flutter-разработчика можно тут!

    Оставьте отзыв
    (минимум 60 знаков)
    Оценка5/5
    Нужно авторизоваться