Joh*_*nal 8 dart flutter flutter-provider
我正在尝试实现 Provider ,它似乎工作正常,但我收到以下消息:
这个 _DefaultInheritedProviderScope 小部件不能被标记为需要构建,因为框架已经在构建小部件的过程中。仅当其祖先之一当前正在构建时,才可以将小部件标记为需要在构建阶段构建。允许此异常是因为框架在子级之前构建父级小部件,这意味着将始终构建脏后代。否则,框架可能不会在此构建阶段访问此小部件。调用 setState() 或 markNeedsBuild() 的小部件是: _DefaultInheritedProviderScope 值:“UserProfile”监听值的实例 进行违规调用时当前正在构建的小部件是:FutureBuilder 脏状态:_FutureBuilderState#bf6ec 当抛出异常,
0 元素.markNeedsBuild。(包:flutter/src/widgets/framework.dart:3896:11)
1 Element.markNeedsBuild(包:flutter/src/widgets/framework.dart:3911:6)
2 _InheritedProviderScopeMixin.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:268:5)
3 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:206:21)
4 UserProfile.user= (package:mdd/core/services/user_info.dart:13:5) ... UserProfile
发送通知是:“UserProfile”的实例
我的代码如下:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authService = Provider.of<AuthService>(context);
final userProfile = Provider.of<UserProfile>(context);
return StatefulWrapper(
onInit: () {
FirebaseNotifications().setUpFirebase();
},
child: FutureBuilder<User>(
future: authService.getUser(),
builder: (context, AsyncSnapshot<User> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.error != null) {
return Text(snapshot.error.toString());
}
userProfile.user = snapshot.data;
// FirebaseUser user = snapshot.data;
return snapshot.hasData ? ListScreen() : LoginScreen();
} else {
return Scaffold(
appBar: AppBar(),
body: Container(),
);
}
},
)
);
}
}
Run Code Online (Sandbox Code Playgroud)
这是 UserProfile 类:
class UserProfile with ChangeNotifier {
User _user = User();
get user {
return _user;
}
set user(User user) {
this._user = user;
notifyListeners();
}
}
Run Code Online (Sandbox Code Playgroud)
以及用于获取配置文件的 AuthService 部分:
Future<User> getUser() async {
print('GETTING THE USER');
final fbaseUser = await _auth.currentUser();
final snapshot = await _db.collection('users')
.document(fbaseUser.uid)
.get();
if (snapshot.data != null) {
Map<dynamic, dynamic> jsres = snapshot.data;
_user = User.fromJson(jsres);
return _user;
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我收到这个错误?我究竟做错了什么?任何人都可以帮我解决这个问题吗?
San*_*att 11
在使用notifylisteners()的帮助下更新状态时我也遇到了同样的问题。
解决方案:-
WidgetsBinding.instance?.addPostFrameCallback((_) {
notifyListeners();
});
Run Code Online (Sandbox Code Playgroud)
您可以在下面复制粘贴运行完整代码,完整代码解决此问题
原因:
此行userProfile.user = snapshot.data;导致错误
FutureBuilder是构建数据,并接收notifyListeners()
来自 Flutter 团队的建议,https://github.com/flutter/flutter/issues/16218#issuecomment-403995076
的FutureBuilder的builder只应建立小工具,它不应该有任何逻辑。构建器可以被任意调用。
解决方案:
在用户情况下,getUser()可以直接设置后UserProfile.user
Step 1: remove final userProfile = Provider.of<UserProfile>(context);
Step 2: move userProfile.user = snapshot.data;logic to futureBuilder'sfuture
FutureBuilder<User>(
future: _future.then((value) =>
Provider.of<UserProfile>(context, listen: false).user = value),
Run Code Online (Sandbox Code Playgroud)
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => UserProfile(),
child: MyApp(),
),
);
}
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({@required this.onInit, @required this.child});
@override
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
if (widget.onInit != null) {
widget.onInit();
}
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
class User {
String name;
User({this.name});
}
Future<User> getUser() async {
print("getUser");
return User(name: "test");
}
class UserProfile with ChangeNotifier {
User _user = User();
get user {
return _user;
}
set user(User user) {
this._user = user;
notifyListeners();
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//final authService = Provider.of<AuthService>(context);
//final userProfile = Provider.of<UserProfile>(context, listen: false);
Future _future = getUser();
return StatefulWrapper(
onInit: () {
//FirebaseNotifications().setUpFirebase();
},
child: FutureBuilder<User>(
future: _future.then((value) =>
Provider.of<UserProfile>(context, listen: false).user = value),
builder: (context, AsyncSnapshot<User> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.error != null) {
return Text(snapshot.error.toString());
}
if (snapshot.hasData) {
return ListScreen();
} else {
return LoginScreen();
}
} else {
return Scaffold(
appBar: AppBar(),
body: Container(),
);
}
},
));
}
}
class ListScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("ListScreen");
}
}
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("LoginScreen");
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9614 次 |
| 最近记录: |