如何在不传递参数的情况下使用riverpod 系列提供程序

Pri*_*nce 7 state-management flutter flutter-provider riverpod

有没有办法访问提供的“ .family”更改通知程序的实例(已经实例化,传递了正确的参数)而无需再次传递参数?

在提供者中

当您创建 ChangeNotifier(需要参数)的提供程序时,您可以获得与它提供的相同的更改通知程序Provider.of<ChangeNotif>(context)

class ChangeNotif extends ChangeNotifier {
  final String id;
  const ChangeNotif(this.id);
}

ChangeNotifierProvider(create: (_) => ChangeNotif("dash"));
Run Code Online (Sandbox Code Playgroud)

一旦使用正确的参数创建了提供者,您就可以在该小部件树的任何位置获取它提供的任何内容,而无需任何类似Provider.of<ChangeNotif("dash")>(context)but 的语法Provider.of<ChangeNotif>(context)

在河港

由于在获取它的实例时必须将参数传递给提供者,因此我不得不将提供者分配给一个变量,以便将其传递给需要提供者提供的更改通知程序的子级。

final changeNotifProvider = ChangeNotifierProvider.family<ChangeNotif, String>((ref, id) => ChangeNotif(id));

class A extends HookWidget {
  build() {
    final _changeNotifProvider = changeNotifProvider("dash");
    final _changeNotif = useProvider(_changeNotifProvider);

    return Column(
     children: [
       B(),
       c(_changeNotifProvider),
     ]
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在_changeNotif不将其作为参数传递给子小部件的情况下获得实例化?有什么方法可以在另一个不是 A 子级的小部件中获取 _changeNotif 的相同实例(例如Provider.of<ChangeNotif>(context)在 Provider 中使用而无需传递新参数)?

Edw*_*nZN 1

查看 Riverpod 示例,了解它如何解决该问题Marvel 示例

使用 Riverpo 系列与 Provider 包的优点是,Provider 不允许您在小部件树中读取同一类的多个实例,并且 RiverPod 系列没有该限制

在提供者中

MultiProvider(
   providers: [
      ChangeNotifierProvider<ChangeNotif>(
        create: (_) => ChangeNotif('dash')
      ),
      ChangeNotifierProvider<ChangeNotif>(
        create: (_) => ChangeNotif('dash2')
      ),
    // and many more of the same provider but different initial value
   ].
   child: MyWidget()
);
Run Code Online (Sandbox Code Playgroud)

然后,在MyWidget执行此操作时Provider.of<ChangeNotif>(context),您只能获得 MultiProvider 创建的最后一个,无法区分同一类型的多个提供程序,现在在 Riverpod 中,解决方案以及传递该系列的一种方法是使用具有初始值的 ScopedProvider。

final _idProvider = ScopedProvider<String>(null);

class A extends HookWidget {

  @override
  Widget build() {
    final _changeNotif = useProvider(changeNotifProvider("dash"));

    return ProviderScope(
      overrides: [
         _idProvider .overrideWithValue("dash"),
      ],
      child: Column(
        children: [
          B(),
          c(),
        ]
      )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

现在所有小部件(B 和 C)都可以读取用于创建系列的参数,如果提供程序已经存在,它将检索它而无需重新创建它

class A extends HookWidget {

  @override
  Widget build() {
    final id = useProvider(_idProvider);
    final _changeNotif = useProvider(changeNotifProvider(id)); //the ProviderContainer will check if there is already a family with that id and retrieve it

    return Text(_changeNotif.id);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这并没有回答问题。 (3认同)