有状态小部件消费者小部件构建两次,因此调用 initState 两次。如何阻止这种情况发生?
因此,对于我的项目,我正在使用 Riverpod,并且正在创建应用程序的主页。 这棵树看起来像这样 ->
CommunityView(Stateful Widget)
WillPopScope
ProviderScope
Consumer
Scaffold
...and so on
现在,在 CommunityView 小部件的构建方法中,
final params = _VSControllerParams(
selectedFamily: widget.selectedFamily,
);
print('familiesStatus: rebuild main');
return WillPopScope(
onWillPop: onWillPop,
child: ProviderScope(
overrides: [_paramsProvider.overrideWithValue(params)],
child: Consumer(
builder: (context, watch, child) {
print('familiesStatus: rebuild consumer');
final state = watch(_vsProvider(params));
final stateController = watch(_vsProvider(params).notifier);
rebuild main
打印仅发生一次,而 rebuild Consumer
打印发生两次。以前的主页获取数据,然后根据网络响应显示获取的数据或错误。现在我使用枚举来获取加载状态,即 ApiStatus.loading 是初始状态,然后 ApiStatus.success 或失败取决于响应。现在我所做的导致此问题的更改是 ->我在 initstate 中添加了一个函数调用,用于获取本地保存的缓存并从中加载数据。那么会发生什么情况是 ApiStatus.loading->ApiStatus.success(已获取缓存)->ApiStatus.loading(以某种方式重建整个小部件)->ApiStatus.success(再次获取缓存)->ApiStatus.success(从互联网)。所以我不确定为什么在获取缓存时第一次重建。
现在为了解决这个问题,我首先尝试在缓存方法调用中查找导致此重建的任何原因,但即使进行大量调试也无法找到任何原因。然后我想创建一个像这样的全局参数
bool fetchDataFromCache = true;
,然后在 initState 内部,我调用像这样的 fetch Cache 方法
if(fetchDataFromCache){
fetchCache();
fetchDataFromCache = false;
}
但这导致 ApiStatus 加载参数像这样改变 ->ApiStatus.loading(initial build)-> ApiStatus.success(已获取缓存)->ApiStatus.loading(以某种方式重建整个小部件)->ApiStatus.success(从互联网获取数据)。所以小部件仍在重建,因为我只在 initState 中设置了 ApiStatus.loading,而没有在其他地方设置。所以还是出问题了。
演示视频 - https://youtu.be/1EzYfCRiwk0
So for my project, I am using Riverpod, and I am creating the home page of my app.
The tree looks like this ->
CommunityView(Stateful Widget)
WillPopScope
ProviderScope
Consumer
Scaffold
...and so on
Now inside the build method of the CommunityView Widget,
final params = _VSControllerParams(
selectedFamily: widget.selectedFamily,
);
print('familiesStatus: rebuild main');
return WillPopScope(
onWillPop: onWillPop,
child: ProviderScope(
overrides: [_paramsProvider.overrideWithValue(params)],
child: Consumer(
builder: (context, watch, child) {
print('familiesStatus: rebuild consumer');
final state = watch(_vsProvider(params));
final stateController = watch(_vsProvider(params).notifier);
The rebuild main
print happens only once, while the rebuild consumer
print happens twice. Previously home page fetched data and then shows data fetched or error depending on network response. Now I use an enum to get loading state, i.e. ApiStatus.loading is the initial state, then ApiStatus.success or failure depending on response. Now what I have changed that is causing this issue is -> I have added a function call in initstate that fetches local saved cache and loads data from that. So what happens is ApiStatus.loading->ApiStatus.success(Cache fetched)->ApiStatus.loading(somehow whole widget rebuild)->ApiStatus.success(cache fetched again)->ApiStatus.success(Data fetched from internet). So I am not sure why it is rebuilding first time when cache is fetched.
Now to fix this, I first tried to find any reason in the cache method call that is causing this rebuild, but was not able to find any even with heavy debugging. Then I thought to create a global parameter which is something like this
bool fetchDataFromCache = true;
and then inside initState, I call fetch Cache method something like this
if(fetchDataFromCache){
fetchCache();
fetchDataFromCache = false;
}
But this caused the ApiStatus loading parameter to change like this ->ApiStatus.loading(initial build)->ApiStatus.success(Cache fetched)->ApiStatus.loading(somehow whole widget rebuild)->ApiStatus.success(Data fetched from internet). So widget is still rebuilding because I have set ApiStatus.loading only in initState, and nowhere else. So it is still glitching out.
Demo video - https://youtu.be/1EzYfCRiwk0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论