提供者:在构建期间调用的 setState() 或 markNeedsBuild()
Posted
技术标签:
【中文标题】提供者:在构建期间调用的 setState() 或 markNeedsBuild()【英文标题】:Provider: setState() or markNeedsBuild() called during build 【发布时间】:2021-08-10 13:36:52 【问题描述】:我正在使用 Hive 存储与 Extension
相关的 Card
项目的整个列表。在所选扩展程序的屏幕中,我正在显示此扩展程序的卡片,并带有一堆过滤器/排序。
为此,我使用ValueListenableBuilder
来获取当前的分机和他们的卡片。
当我过滤/排序此列表时,我想将它们存储到我的Provider
类中,因为我想将此列表重用到另一个屏幕中。
但我们是context.read<ShowingCardsProvider>().setAll(sortedList)
,我收到了这个错误:
setState() or markNeedsBuild() called during build.
我现在不在任何地方听ShowingCardsProvider
。
你能解释一下这里出了什么问题吗?
谢谢!
main.dart
runApp(MultiProvider(
providers: [
ChangeNotifierProvider.value(value: AuthProvider()),
ChangeNotifierProvider.value(value: UserProvider()),
ChangeNotifierProvider.value(value: ShowingCardsProvider()),
],
child: MyApp(),
));
showing_cards_provider.dart
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:pokecollect/card/models/card.dart';
class CardsProvider extends ChangeNotifier
final List<CardModel> _items = [];
UnmodifiableListView<CardModel> get items => UnmodifiableListView(_items);
void setAll(List<CardModel>? items)
_items.clear();
if (items != null || items!.isNotEmpty)
_items.addAll(items);
notifyListeners();
void addAll(List<CardModel> items)
_items.addAll(items);
notifyListeners();
void removeAll()
_items.clear();
notifyListeners();
extension_page.dart
@override
Widget build(BuildContext context)
return Scaffold(
extendBodyBehindAppBar: true,
body: SafeArea(
child: LayoutBuilder(builder: (context, constraints)
return CustomScrollView(
slivers: [
SliverAppBar(
...
),
...
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
sliver: ValueListenableBuilder(
valueListenable: ExtensionBox.box.listenable(keys: [_extensionUuid]),
builder: (ctx, Box<Extension> box, child)
List<CardModel>? cardsList = box
.get(_uuid)!
.cards
?.where((card) => _isCardPassFilters(card))
.cast<CardModel>()
.toList();
var sortedList = _simpleSortCards(cardsList);
context.read<ShowingCardsProvider>().setAll(sortedList);
return _buildCardListGrid(sortedList);
,
),
),
]
);
),
),
);
【问题讨论】:
【参考方案1】:这确实是因为我正在使用ValueListenableBuilder
,并且在构建小部件时,notifyListeners
被调用(进入我的提供程序)。
我的修补程序是这样做的:
return Future.delayed(
Duration(milliseconds: 1),
() => context.read<ShowingCardsProvider>().setAll(list),
);
不是很漂亮,但很管用?
如果你有更优雅的方式,欢迎评论!
【讨论】:
以上是关于提供者:在构建期间调用的 setState() 或 markNeedsBuild()的主要内容,如果未能解决你的问题,请参考以下文章
“在构建期间调用 setState() 或 markNeedsBuild()”错误尝试在消费者小部件(提供程序包)内的导航器中推送替换
错误:在构建期间调用了 setState() 或 markNeedsBuild()
Flutter:在构建期间调用 setState() 或 markNeedsBuild()
在构建期间调用 setState() 或 markNeedsBuild() - Flutter