[英]Threw an exception when the notifier tried to update its state error in flutter_riverpod
I am developing an app with flutter and I am using flutter_riverpod package for state managment.我正在使用 flutter 开发一个应用程序,并且我正在使用 flutter_riverpod package 进行 state 管理。 But I am getting an error.但我收到一个错误。
I have 2 main widget inside my screen.我的屏幕内有 2 个主要小部件。 These are "ReadTopBarW" widget and "ReadArticleW" widget.这些是“ReadTopBarW”小部件和“ReadArticleW”小部件。 I am getting datas with http post with futureprovider with riverpod.我正在使用带有 Riverpod 的 futureprovider 的 http 帖子获取数据。 There is no problem so far.到目前为止没有问题。 My purpose is change the icon with a response value.我的目的是用响应值更改图标。 I am getting the value in "ReadArticleW" and I am writing the value for StateProvider.我在“ReadArticleW”中获得了值,并且正在为 StateProvider 编写值。 And I will watch the value in "ReadTopBarW".我会观察“ReadTopBarW”中的值。
This is my "ReadArticleW"这是我的“ReadArticleW”
import 'dart:convert';
import 'package:eem_flutter_app/services/get_one_article.dart';
import 'package:eem_flutter_app/widgets/read/shimmer_read_w.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final isSavedVider = StateProvider((_) => '');
class ReadArticleW extends ConsumerWidget {
const ReadArticleW({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final futureCatFacts = ref.watch(singleArticleFProvider);
return SingleChildScrollView(
child: futureCatFacts.when(
data: (datax) {
final decodedData = json.decode(datax.body);
final isSaved = decodedData[1].toString();
ref.read(isSavedVider.notifier).state = isSaved;
return Column(
children: [
Text(
decodedData[0]['articleTitle'].toString(),
),
Image.network(
decodedData[0]['articleLImage'].toString()),
],
);
},
error: (err, stack) => Text('Error: $err'),
loading: () => const ShimmerReadW(),
),
);
}
}
This my "ReadTopBarW"这是我的“ReadTopBarW”
import 'package:eem_flutter_app/widgets/read/read_article_w.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class ReadTopBarW extends ConsumerWidget {
const ReadTopBarW({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final x = ref.watch(isSavedVider);
print(x);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
Navigator.pop(context);
},
child: const Icon(Icons.arrow_back_ios)),
Row(
children: const [
"0" == "1"
? Icon(Icons.bookmark_border)
: Icon(Icons.bookmark_outlined),
SizedBox(
width: 10,
),
Icon(Icons.ios_share),
],
),
],
);
}
}
This is error text.这是错误文本。 The error is vscode red error that you know错误是你知道的vscode红色错误
Exception has occurred.
StateNotifierListenerError (At least listener of the StateNotifier Instance of 'StateController<String>' threw an exception
when the notifier tried to update its state.
The exceptions thrown are:
setState() or markNeedsBuild() called during build.
This UncontrolledProviderScope widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
UncontrolledProviderScope
The widget which was currently being built when the offending call was made was:
ReadArticleW
Please focus on th isSavedVider because the problem is here.请关注 isSavedVider,因为问题就在这里。 There is no problem in singleArticleProvider. singleArticleProvider 没有问题。
note: I simplified the code to publish here.注意:我简化了在此处发布的代码。
You shouldn't update a StateProvider
in the build
method, the error is coming from here:您不应该在build
方法中更新StateProvider
,错误来自这里:
child: futureCatFacts.when(
data: (datax) {
final decodedData = json.decode(datax.body);
final isSaved = decodedData[1].toString();
ref.read(isSavedVider.notifier).state = isSaved;
What you can you is watch
the singleArticleFProvider
in isSavedVider
and set the value from the extracted response, this way, when there is an update to the response, it isSavedVider
gets the update value like so:您可以在watch
中isSavedVider
singleArticleFProvider
从提取的响应中设置值,这样,当响应有更新时, isSavedVider
会像这样获取更新值:
final isSavedVider = StateProvider((ref){
final futureCatFacts = ref.watch(singleArticleFProvider);
if(futureCatFacts is AsyncData){
final decodedData = json.decode(futureCatFacts.value.body);
final isSaved = decodedData[1].toString();
return isSaved;
}
return "";
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.