简体   繁体   English

Flutter:无法调用提供商<t> .of(context) 来自定义在另一个文件中的 function。 ProviderNotFoundException</t>

[英]Flutter: Can't call Provider<T>.of(context) from a function that is defined into another file. ProviderNotFoundException

I'm new to flutter and I wish to organize my folders in order to write cleaner code.我是 flutter 的新手,我希望整理我的文件夹以编写更清晰的代码。 I'm trying to divide my flutter page on three parts:我试图将我的 flutter 页面分为三个部分:

  1. login_view.dart (this view will be rendered as the login view and will call functions defined into login_builder.dart to build each of its widgets) login_view.dart (此视图将呈现为登录视图,并将调用定义在 login_builder.dart 中的函数来构建其每个小部件)
  2. login_builder.dart (contains function definitions called by login_view.dart to build widgets) login_builder.dart (包含由 login_view.dart 调用的 function 定义以构建小部件)
  3. login_state.dart (for state management) login_state.dart (用于state管理)

But when I call Provider.of(context) inside a functiton that is defined into login_builder.dart (out of the login_view.dart widget tree) it always throws ProviderNotFoundException但是当我在定义为 login_builder.dart 的函数中调用Provider.of(context)时(在 login_view.dart 小部件树之外),它总是抛出ProviderNotFoundException

// login_view.dart // login_view.dart

import 'package:discover/ui/views/login/login_builder.dart';
import 'package:discover/ui/views/login/login_state.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Login extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LoginState>(
      create: (context) => LoginState(),
      child: buildLoginForm(context), 
    );
  }
}

// login_builder.dart // login_builder.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:discover/ui/views/login/login_state.dart';

Widget buildLoginForm(BuildContext context) {
  var loginState = Provider.of<LoginState>(context);
  return Form(
    child: Column(
      children: <Widget>[
        TextFormField(
          onChanged: (value) => loginState.userName = value,
        )
      ],
    ),
  );
}

// login_state.dart // login_state.dart

import 'package:flutter/material.dart';

class LoginState extends ChangeNotifier {
  String _userName = "";

  String get userName => _userName;

  set userName(String userName) {
    _userName = userName;
  }
}

// Debug Console // 调试控制台

════════ Exception caught by widgets library ═══════════════════════════════════
The following ProviderNotFoundException was thrown building Login(dirty):
Error: Could not find the correct Provider<LoginState> above this Login Widget

To fix, please:

  * Ensure the Provider<LoginState> is an ancestor to this Login Widget
  * Provide types to Provider<LoginState>
  * Provide types to Consumer<LoginState>
  * Provide types to Provider.of<LoginState>()
  * Ensure the correct `context` is being used.

If none of these solutions work, please file a bug at:
https://github.com/rrousselGit/provider/issues

The relevant error-causing widget was
    Login
When the exception was thrown, this was the stack
Provider.of
buildLoginForm
Login.build
StatelessElement.build
ComponentElement.performRebuild

The context you passed to login_builder is the same context that was passed to login_view, so it exists in a place of the widget tree above where you inserted your ChangeNotifierProvider which is why you can't find it with Provider.of .您传递给 login_builder 的context与传递给 login_view 的上下文相同,因此它存在于您插入ChangeNotifierProvider的上方小部件树的位置,这就是为什么您无法使用Provider.of找到它的原因。 In order to get this to work the way you want it to, you need to utilize a Builder widget to gain a new BuildContext that exists below the provider:为了让它按照你想要的方式工作,你需要利用一个Builder小部件来获得一个新的BuildContext存在于提供者之下:

class Login extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LoginState>(
      create: (context) => LoginState(),
      child: Builder(builder: buildLoginForm), 
    );
  }
}

Now the context passed to buildLoginForm will be the context for the Builder (which exists below the provider) instead of for your Login widget (which exists above the provider).现在传递给buildLoginForm的上下文将是Builder的上下文(存在于提供者之下),而不是您的Login小部件(存在于提供者之上)的上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法从 flutter 中的另一个文件调用 class - Can't call class from another file in flutter flutter - 无法调用另一个文件中的方法 - flutter - can't call a method in another file 抛出 providernotfoundexception(t, context.widget.runtimetype); - throw providernotfoundexception(t, context.widget.runtimetype); Flutter:无法从 showModalBottomSheet 访问 Provider - Flutter: can't access Provider from showModalBottomSheet 预期的 ';' 在这之后。 , stthrow ProviderNotFoundException(T, context.widget.runtimeType) - Expected ';' after this. , stthrow ProviderNotFoundException(T, context.widget.runtimeType) Flutter - 调用另一个 dart 文件中定义的函数来刷新 ListView - Flutter - Call a function defined in another dart file to refresh a ListView 如何从 Flutter 中的另一个文件调用 function? - How to call a function from another file in Flutter? 如何从 Flutter 中的另一个文件访问用户定义的 function - How to access user defined function from another file in Flutter 崩溃报告“字符串-无法下载或获取文件”的任何线索。 来自Sentry-Flutter App? - Any clue for crash report 'String - Couldn't download or retreive file.' got from Sentry - Flutter App? 我无法让 function 从另一个文件工作 - I can't get a function to work from another file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM