You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Provider的dispose方法未触发问题咨询

问题原因

你当前的代码只是通过Provider.of获取了ForgotPasswordPageProvider的实例,但这个Provider的生命周期并没有和ForgotPasswordPage绑定在一起。只有当Provider是在页面的作用域内创建(比如用ChangeNotifierProvider包裹页面),页面销毁时才会触发Provider的dispose方法。

解决方案

有两种常用的方式可以让Provider和页面生命周期绑定,触发dispose:

方式一:在GoRouter路由配置中绑定Provider

修改你的GoRouter路由配置,用ChangeNotifierProvider包裹ForgotPasswordPage,这样页面出栈时Provider会自动调用dispose:

GoRoute(
  path: '/forgot-password',
  builder: (context, state) {
    return ChangeNotifierProvider(
      create: (_) => ForgotPasswordPageProvider(),
      child: const ForgotPasswordPage(),
    );
  },
)

方式二:在页面内部包裹Provider

修改ForgotPasswordPage的build方法,用ChangeNotifierProvider作为根组件,确保Provider和页面同生命周期:

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => ForgotPasswordPageProvider(),
    child: Consumer<ForgotPasswordPageProvider>(
      builder: (context, provider, child) {
        return Scaffold(
          appBar: CustomAppBar(
            leading: IconButton(
              onPressed: () {
                GoRouter.of(context).pop();
              },
              icon: const FaIcon(FontAwesomeIcons.xmark),
            ),
            title: "Reset password",
          ),
          body: Padding(
            padding: EdgeInsets.symmetric(
                horizontal: 24,
                vertical: MediaQuery.of(context).size.height * 0.06),
            child: Form(
              key: provider.formKey,
              child: Column(
                children: [
                  Hero(
                    tag: "logo",
                    child: FaIcon(
                      FontAwesomeIcons.comments,
                      color: Theme.of(context).colorScheme.primary,
                      size: 96,
                    ),
                  ),
                  SizedBox(height: MediaQuery.of(context).size.height * 0.02),
                  FormInputField(
                    controller: provider.textEditingController,
                    hintText: "Enter your email address",
                    keyboardType: TextInputType.emailAddress,
                    textInputAction: TextInputAction.done,
                    validator: FormValidator.emailValidator,
                    label: "E-mail",
                  ),
                  SizedBox(height: MediaQuery.of(context).size.height * 0.02),
                  FilledButton(
                    onPressed: () {
                      if (provider.formKey.currentState!.validate()) {}
                    },
                    child: const Text("Reset password"),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    ),
  );
}
补充说明
  • 不要直接在全局或者上层作用域创建这个Provider,否则页面销毁时Provider不会被销毁,也就不会触发dispose。
  • 用Consumer而非直接Provider.of可以避免不必要的组件重建,优化页面性能。

内容的提问来源于stack exchange,提问作者Abel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:28:18