Flutter:无法从定义到另一个文件的函数中调用 Provider<T>.of(context)。 ProviderNotFoundException异常
Flutter: Can't call Provider<T>.of(context) from a function that is defined into another file. ProviderNotFoundException
我是 Flutter 的新手,我希望整理我的文件夹以便编写更清晰的代码。
我试图将我的 flutter 页面分为三个部分:
- login_view.dart(此视图将呈现为登录视图,并将调用定义到 login_builder.dart 中的函数来构建其每个小部件)
- login_builder.dart(包含由 login_view.dart 调用以构建小部件的函数定义)
- login_state.dart(用于状态管理)
但是当我在定义到 login_builder.dart 的函数中调用 Provider.of(context)(在 login_view.dart 小部件树之外) 它总是抛出 ProviderNotFoundException
// 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
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
import 'package:flutter/material.dart';
class LoginState extends ChangeNotifier {
String _userName = "";
String get userName => _userName;
set userName(String userName) {
_userName = userName;
}
}
//调试控制台
════════ 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
您传递给 login_builder 的 context
与传递给 login_view 的上下文相同,因此它存在于您插入 [=] 上方的小部件树的位置12=] 这就是为什么你不能用 Provider.of
找到它的原因。为了让它按照你想要的方式工作,你需要利用一个 Builder
小部件来获得一个新的 BuildContext
,它存在于提供者下面:
class Login extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<LoginState>(
create: (context) => LoginState(),
child: Builder(builder: buildLoginForm),
);
}
}
现在,传递给 buildLoginForm
的上下文将是 Builder
(存在于提供程序下方)的上下文,而不是您的 Login
小部件(存在于提供程序上方)的上下文.
我是 Flutter 的新手,我希望整理我的文件夹以便编写更清晰的代码。 我试图将我的 flutter 页面分为三个部分:
- login_view.dart(此视图将呈现为登录视图,并将调用定义到 login_builder.dart 中的函数来构建其每个小部件)
- login_builder.dart(包含由 login_view.dart 调用以构建小部件的函数定义)
- login_state.dart(用于状态管理)
但是当我在定义到 login_builder.dart 的函数中调用 Provider.of(context)(在 login_view.dart 小部件树之外) 它总是抛出 ProviderNotFoundException
// 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
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
import 'package:flutter/material.dart';
class LoginState extends ChangeNotifier {
String _userName = "";
String get userName => _userName;
set userName(String userName) {
_userName = userName;
}
}
//调试控制台
════════ 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
您传递给 login_builder 的 context
与传递给 login_view 的上下文相同,因此它存在于您插入 [=] 上方的小部件树的位置12=] 这就是为什么你不能用 Provider.of
找到它的原因。为了让它按照你想要的方式工作,你需要利用一个 Builder
小部件来获得一个新的 BuildContext
,它存在于提供者下面:
class Login extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<LoginState>(
create: (context) => LoginState(),
child: Builder(builder: buildLoginForm),
);
}
}
现在,传递给 buildLoginForm
的上下文将是 Builder
(存在于提供程序下方)的上下文,而不是您的 Login
小部件(存在于提供程序上方)的上下文.