Riverpod в классе или вне метода сборки?

Я хочу создать класс и объединить похожие методы.

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

Модель

      class User {
final String uid;
final String username;
final String email;

User({required this.uid, required this.username, required this.email});}

Уведомление о состоянии

      import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/user.dart';

class UserProvider extends StateNotifier<User> {
UserProvider()
  : super(User(
      email: '',
      username: 'default',
      uid: '',
    ));

addUser(User user) {
state = user;
}}

Место использования / класс

      import 'package:cloud_firestore/cloud_firestore.dart';
import '../providers/user_provider.dart';
import '../models/user.dart' as model;



class FirestoreMethods {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

// HOW TO USE RIVERPOD HERE IN PLACE OF PROVIDER.
// EXAMPLE OF PROVIDER-
// final user = Provider.of<UserProvider>(context, listen: false);
// print(user.email);
// print(user.uid);
// print(user.username);

// Example of Riverpod
// final userProvider = StateNotifierProvider<UserProvider, 
// model.User>((ref) => UserProvider());
// ABOVE RIVERPOD DOES NOT WORK HERE
}

2 ответа

@AnmolSingh При создании StateNotifierProvider вы можете напрямую передать класс модели пользователя. Я изменил ваш код. Если вы нажмете потрясающую кнопку, она обновит состояние провайдера userProvider и обновит пользовательский интерфейс. Вы можете запустить этот код в самом дартпаде.

      import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(userProvider);
    return MaterialApp(
        theme: ThemeData.dark().copyWith(
          scaffoldBackgroundColor: darkBlue,
    ),
    debugShowCheckedModeBanner: false,
    home: Scaffold(
      body: Center(
        child: Text("UserName: ${user.username}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          ref.read(userProvider.notifier).addUser(User(
                email: "krishnakumar@riverpod.com",
                uid: "1",
                username: "MSARKrish",
              ));
        },
      ),
    ));
  }
}

class User {
  final String uid;
  final String username;
  final String email;

  User({required this.uid, required this.username, required this.email});
}

class UserProvider extends StateNotifier<User> {
  UserProvider()
      : super(User(
          email: '',
          username: 'default',
          uid: '',
        ));

  addUser(User user) {
    state = user;
  }
}

final userProvider =
    StateNotifierProvider<UserProvider, User>((ref) => UserProvider());

Вы можете передать ref как параметр для любого класса

      class FirestoreMethods
{
  FirestoreMethods(this.ref)
  final Ref ref;
}

Вот универсальное решение.

  1. Создайте RefHolder, который получитRefссылка изDummyProvider. Я назвал его Dummy, потому что на самом деле он ничего не дает.

            class DummyNotifier extends Notifier<bool> {
     @override
     bool build() {
       refHolder = RefHolder._(ref);
       return true;
     }
    }
    
    final dummyProvider = NotifierProvider<DummyNotifier, bool>(() {
      return DummyNotifier();
     });
    
    late RefHolder refHolder;
    
    class RefHolder {
     final Ref _ref;
     RefHolder._(this._ref);
    
     get ref {
      return _ref;
     }
    }
    
  2. Прочтите поставщика из метода сборки MainApp, чтобы убедиться, что синглтон RefHolder создан.

             Widget build(BuildContext context, WidgetRef ref) {
        ref.read(dummyProvider);
    
  3. Используйте из любого места. Например, из метода локальных уведомлений:

            Future _showNotificationWithDefaultSound(notifPlugin) async {
    
      Ref ref = refHolder.ref;
    
      //use ref to get required info from providers
    

Гитхаб

Другие вопросы по тегам