Riverpod Provider.family 和 HookConsumerWidget 不刷新 UI

问题描述 投票:0回答:1

我很难理解为什么 Riverpod 和 Hook 的 UI 不刷新,尤其是在使用

HookConsumerWidget
ProviderFamily
传递一个参数时。

一些精度:

MediaThumbnail
MediaThumbnailAPI
调用,并为其设置了唯一的键,
MediaThumbnailAPI
位于gridviewbuilder内部(gridviewbuilder内的项目可以独立重建而不重建整个gridview吗?我认为这是可能的) .

我的理解是,当长按时, bool

isFavorite = ref.watch(favoriteFamilyProvider(id)).isMediaFavorite(id);
不会触发
setState
(相当于 Riverpod 钩子),但我不知道我的语法中缺少什么。

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../../../favorite_provider.dart';
import 'package:universal_io/io.dart' as universal_io;

class MediaThumbnail extends HookConsumerWidget {
  final String id;
  final String fileExtension;
  final universal_io.File imageFile;
  final String urlEndpoint;
  final String description;
  final double thumbnailRadius;
  final String mimeType;

  const MediaThumbnail(this.imageFile, this.urlEndpoint, this.id,
      this.fileExtension, this.description, this.thumbnailRadius, this.mimeType,
      {Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    bool isFavorite = ref.watch(favoriteFamilyProvider(id)).isMediaFavorite(id); // probably the problematic line of code.
    return GestureDetector(
        behavior: HitTestBehavior.translucent,
        onLongPress: () {

          ref.read(favoriteProvider.notifier)
              .toggleFav(id, fileExtension, description); // this one works successfully and change the content of imageMetadataBox 
          isFavorite = ref.read(favoriteFamilyProvider(id)).isMediaFavorite(id); // the isFavorite value is correctly updated
          print("is favorite: $isFavorite");
        },
       
        child: Stack(children: [
          Container(
              constraints: const BoxConstraints.expand(),
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: FileImage(imageFile), fit: BoxFit.cover),
              )),
          if (isFavorite) // this does not refresh
            Positioned(
              top: 5,
              left: 60,
              right: .0,
              child: Center(
                child: Stack(
                  children: [
                    _buildIcon(16, Colors.white),
                    _buildIcon(13, Colors.pinkAccent),
                  ],
                ),
              ),
            )
        ]));
  }
}

favorite_provider.dart

final favoriteFamilyProvider =
Provider.family<FavoriteFamilyNotifier, String>(
        (_, myId) => FavoriteFamilyNotifier(myId));

class FavoriteFamilyNotifier extends StateNotifier<bool> {
  FavoriteFamilyNotifier(String myId) : super(false) {}

  bool isMediaFavorite(String myId) {
    Store store = objectbox.store;

    Box<MediaMetadata> imageMetadataBox = store.box<MediaMetadata>();

    final qBuilder =
       imageMetadataBox.query(MediaMetadata_.myId.equals(myId));
    final query = qBuilder.build();
    var results = query.find();
    bool isFavorite = results.isNotEmpty;
    print("$myId is favorite? $isFavorite");
    return isFavorite;
  }

非常感谢那些对这个库有经验的人。

注意:我使用“myId”是因为ObjectBox为其内部数据库保留了“id”关键字,因此

MediaMetadata_.myId
就像一个32长的字符串,而
MediaMetadata_.id
是一个无符号整数。

flutter setstate riverpod flutter-state
1个回答
0
投票

您的问题似乎是您正在使用

Provider
来实现扩展
StateNotifier
的类。要解决此问题,请将
Provider
更改为
StateNotifierProvider

我还想指出

StateNotifier
是一种已弃用的做法。使用
Notifier
来实现您的
FavoriteFamilyNotifier

myId
方法中使用
isMediaFavorite()
字段似乎也更符合逻辑,您在创建
FavoriteFamilyNotifier(myId)
时将其作为字段传递。 或者去掉
.family
,因为如果你用
FavoriteFamilyNotifier(String myId)
创建一个类,然后根本不使用该字段,那么根本不清楚它扮演什么角色。

并且不太清楚为什么使用

HookConsumerWidget
,在本示例中的小部件内部没有使用它。

© www.soinside.com 2019 - 2024. All rights reserved.