刷新 riverpod 状态当回到上一页时

huangapple go评论62阅读模式
英文:

(go-router) Refresh riverpod state when going to a previous page

问题

我正在使用 go_router 9.0.1 和 go_router_builder 2.2.0 以及 riverpod 2.3.6。
我已经在我的项目中实现了 go_router,默认情况下,当进入子路由时,该包会保持前一个页面的状态。在我的情况下,我希望每次进入页面时,该页面都会重新加载/重建。

例如,我有两个路由:

  • page1,包括子路由如 page1/sub1Page1page1/sub2Page1
  • page2,包括子路由如 page2/sub1Page1page2/sub2Page1

如果我从 page1 转到 page1/sub1Page1,使用类型安全的方法 Page1().go(context),我希望从 page1/sub1Page1 返回到 page1 时,我的 riverpod 提供程序的状态会重置。这意味着我需要在推送另一页之前手动重置我的提供程序,使用 ref.invalidate(myProvider)。是否存在解决此行为的解决方案?

我目前简化的 go_router 实现如下:

GoRouter(
      routes: $appRoutes,
      initialLocation: initialLocation,
      debugLogDiagnostics: true,
    );
@TypedShellRoute<HomeRoute>(
  routes: <TypedRoute<GoRouteData>>[
   TypedGoRoute<Page1Route>(
      path: Page1Route.path,
      name: Page1Route.name,
      routes: <TypedGoRoute<GoRouteData>>[
         TypedGoRoute<Sub1Page1>(
                  path: Sub1Page1.path,
                  name: Sub1Page1.name,
                ),
         TypedGoRoute<Sub2Page1>(
                  path: Sub2Page1.path,
                  name: Sub2Page1.name,
                ),
      ]
      TypedGoRoute<Page2>(
                  path: Page2.path,
                  name: Page2.name,
                ),
]);
class HomeRoute extends ShellRouteData {
  const HomeRoute();

  @override
  Widget builder(BuildContext context, GoRouterState state, Widget navigator) =>
      Layout(child: navigator);
}

class Page1 extends GoRouteData {
  const ProjectsRoute();

  static const String name = kNamePage1;
  static const String path = kPathPage1 ;

  @override
  Widget build(BuildContext context, GoRouterState state) => Page1Screen();
}

// 请注意,所有页面或子页面的声明方式与上述代码相同。
英文:

I am using using go_router 9.0.1 and go_router_builder 2.2.0 with riverpod 2.3.6.
I have implemented go_router in my project and by default the package maintain the state of the previous page when using going to a sub-route. In my case I want that each time i go to a page, this same page reload/rebuild itself.

For example I have 2 routes :

  • page1 with subroutes like page1/sub1Page1 or - page1/sub2Page1
  • page2 with subroutes like page2/sub1Page1 or - page2/sub2Page1

If I go from page1 to page1/sub1Page1 using the Page1().go(context) method since I am using the type safe methods. I want to go back from page1/sub1Page1 to the page1 with the Page1().go(context) the state of the my riverpod provider is the same. It store the Page1 widget state somewhere meaning that I need to manually reset my providers manually using ref.invalidate(myProvider) before pushing another page. Does a solution exist to have this behavior ?

My current simplify implementation of go_router:

GoRouter(
      routes: $appRoutes,
      initialLocation: initialLocation,
      debugLogDiagnostics: true,
    );
@TypedShellRoute<HomeRoute>(
  routes: <TypedRoute<GoRouteData>>[
   TypedGoRoute<Page1Route>(
      path: Page1Route.path,
      name: Page1Route.name,
      routes: <TypedGoRoute<GoRouteData>>[
         TypedGoRoute<Sub1Page1>(
                  path: Sub1Page1.path,
                  name: Sub1Page1.name,
                ),
         TypedGoRoute<Sub2Page1>(
                  path: Sub2Page1.path,
                  name: Sub2Page1.name,
                ),
      ]
      TypedGoRoute<Page2>(
                  path: Page2.path,
                  name: Page2.name,
                ),
]);
class HomeRoute extends ShellRouteData {
  const HomeRoute();

  @override
  Widget builder(BuildContext context, GoRouterState state, Widget navigator) =>
      Layout(child: navigator);
}

class Page1 extends GoRouteData {
  const ProjectsRoute();

  static const String name = kNamePage1;
  static const String path = kPathPage1 ;

  @override
  Widget build(BuildContext context, GoRouterState state) => Page1Screen();
}

// Note that all the page or subpage are declared exactly as above.

答案1

得分: 1

这是您要翻译的内容:

"It is possible by not maintain the state of a page but with the go_router package the feature is hidden.

In the MaterialApp widget an parameter maintainState is available. But since we are using MaterialApp.router this parameter is no longer available.

Is will appear again with the package only when we are trying to make a custom transition.
We can find this example in the documentation:

class FancyRoute extends GoRouteData {
  @override
  MaterialPage<void> buildPage(BuildContext context, GoRouterState state) =>
    CustomTransitionPage<void>(
      key: state.pageKey,
      child: FancyPage(),
      transitionsBuilder: (context, animation, animation2, child) =>
          RotationTransition(turns: animation, child: child),
    ),
}

The CustomTransitionPage is based on the MaterialPage widget where here again the maintainState property is available and where you need to set to false since by default it's to true.
If you are in my case and don't want any animation between page, do not use the NoTransitionPage<T> class since this parameter is not available.

I have created then based on their implementation of the no transition page a custom one below where the maintain state is false. You can then use it as documented in the go router package.

/// Custom transition page with no transition.
class CustomNoTransitionPage<T> extends CustomTransitionPage<T> {
  /// Constructor for a page with no transition functionality.
  const CustomNoTransitionPage({
    required super.child,
    super.name,
    super.arguments,
    super.restorationId,
    super.key,
  }) : super(
          transitionsBuilder: _transitionsBuilder,
          transitionDuration: Duration.zero,
          reverseTransitionDuration: Duration.zero,
          maintainState: false,
        );

  static Widget _transitionsBuilder(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) =>
      child;
}
英文:

It is possible by not maintain the state of a page but with the go_router package the feature is hidden.

In the MaterialApp widget an parameter maintainState is available. But since we are using MaterialApp.router this parameter is no longer available.

Is will appear again with the package only when we are trying to make a custom transition.
We can find this example in the documentation:

class FancyRoute extends GoRouteData {
  @override
  MaterialPage<void> buildPage(BuildContext context, GoRouterState state) =>
    CustomTransitionPage<void>(
      key: state.pageKey,
      child: FancyPage(),
      transitionsBuilder: (context, animation, animation2, child) =>
          RotationTransition(turns: animation, child: child),
    ),
}

The CustomTransitionPage is based on the MaterialPage widget where here again the maintainState property is available and where you need to set to false since by default it's to true.
If you are in my case and don't want any animation between page, do not use the NoTransitionPage<T> class since this parameter is not available.

I have created then based on their implementation of the no transition page a custom one below where the maintain state is false. You can then use it as documented in the go router package.

/// Custom transition page with no transition.
class CustomNoTransitionPage<T> extends CustomTransitionPage<T> {
  /// Constructor for a page with no transition functionality.
  const CustomNoTransitionPage({
    required super.child,
    super.name,
    super.arguments,
    super.restorationId,
    super.key,
  }) : super(
          transitionsBuilder: _transitionsBuilder,
          transitionDuration: Duration.zero,
          reverseTransitionDuration: Duration.zero,
          maintainState: false,
        );

  static Widget _transitionsBuilder(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget child,
  ) =>
      child;
}

huangapple
  • 本文由 发表于 2023年7月10日 20:19:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定