flutter_riverpod -当上下文可用时访问引用

whlutmcx  于 2022-11-25  发布在  Flutter
关注(0)|答案(1)|浏览(132)

我正在迁移我的应用以使用flutter_riverpod包。目前,我的应用正在使用provider包来管理/处理应用状态。
我在多个实用程序类中有很多静态方法,它们将BuildContext作为输入。我使用上下文来访问提供程序,这允许我读取和修改状态:

// This relies on the provider package
abstract class SomeRandomUtilityClass {

  static FutureOr<String?> redirect(BuildContext context) {
    bool isSignedIn = context.read<AuthProvider>().isSignedIn;
  
    if (!isSignedIn) {
      return '/signIn';
    } else {
      return null;
    }
  }

我如何使用Riverpod实现这一点?据我所知,您需要一个Ref才能从/向提供程序读取/写入,但我甚至不确定API是否允许。
我试着用Ref对象替换我的方法的BuildContext参数,但是我很难找到一个对象,我只能访问一个WidgetRef

class App extends ConsumerWidget {
  /** ... **/

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp.router(
      /** ... **/
      routerConfig: GoRouter(
        /** ... **/
        routes: [
          GoRoute(
            /** ... **/
            // This doesn't work, because the method I'm calling expects a Ref,
            // and not a WidgetRef.
            redirect: (_, __) => SomeRandomUtilityClass.redirect(ref),
          ),
        ],
      ),
    );
  }
}

一个简单的修复方法是通过将参数的类型从Ref更改为WidgetRef来修改我的静态方法,但是Riverpod包的维护人员说传递WidgetRef s是个坏主意。
我可能误会了什么。如果我是的话请告诉我。

ffscu2ro

ffscu2ro1#

正如你所说,是的,WidgetRefRef是两种不同的类型,因此错误。
要理解其中的原因,请考虑以下情况:传递WidgetRef是一个坏主意 * 因为 * WidgetRef(实际上)链接了它们的Widget的 * 元素 。它们的生命周期实际上与小部件的生命周期相关联,而提供者的生命周期则是另一回事。在某种程度上,WidgetRef更接近于AutoDisposeRef
但是传递WidgetRef是危险的,因为从技术上讲,你可以用一种不适合Riverpod的方式将小部件标记为脏。
长话短说,
一般来说 *,您很可能希望将静态方法重构为单个简单的提供者,最终,它只是一个带有ref Package 器的函数。
我强烈建议您也使用riverpod_annotation,这样可以节省时间 并且可以获得可读性强、简洁(而且没有麻烦)的内容:

@riverpod
T yourFunction(YourFunctionRef ref) {
  final someValue = ref.watch(someDependencyProvider);

  // logic

  return someComputedValue; // Type T
}

在您的 * 特定 * 用例中,您尝试使用go router和riverpod实现重定向。我会避免创建这样一个简单的提供程序,因为它会导致应用的根在auth更改时重建。
那是一个“深刻”的主题,而且有几种方法可以这样做;我创建了一个repo here来演示如何解决这个问题。
检查complete_example文件夹,那里有一个完整的例子,* 或 * 在其他文件夹中搜索更老和更简单的例子。

相关问题