ProviderScope 和 Riverpod 提供程序会从内存中删除吗?

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

我很困惑,Nested ProviderScope 和所有 Providers 是否会从内存中删除?遵循用例是好的实践还是坏的实践?

我有idsProvider

final idsProvider = Provider((_) => List.generate(50, (i) => i));

并为 idsProvider 的每个 id 提供 itemIdProvider

final itemIdProvider = Provider.autoDispose((_) => 0);

界面如下:

class BuildListView extends ConsumerWidget {
  const BuildListView({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final ids = ref.watch(idsProvider);

    return ListView.builder(
      itemCount: ids.length,
      itemBuilder: (context, index) {
        return ProviderScope(
          overrides: [
            itemIdProvider.overrideWithValue(ids[index]),
          ],
          child: const BuildItem(),
        );
      },
    );
  }
}

class BuildItem extends ConsumerWidget {
  const BuildItem({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final itemState = ref.watch(itemProvider);

    return itemState.when(
      data: (id, data) => ListTile(
        title: Text("ID: $id"),
        subtitle: Text(data),
      ),
      loading: () => const CircularProgressIndicator(),
      error: (error) => Text(error.toString()),
    );
  }
}

然后我有 stateNotifierProvider 来操作 ListView 的每个项目的状态:

final itemProvider = StateNotifierProvider.autoDispose<ItemNotifier, ItemState>(
  (ref) => ItemNotifier(ref.watch(itemIdProvider)),
  dependencies: [itemIdProvider],
);

class ItemNotifier extends StateNotifier<ItemState> {
  ItemNotifier(this.id) : super(const ItemState.loading()) {
    fetchData();
  }

  final int id;

  Future<void> fetchData() async {
    await Future.delayed(const Duration(seconds: 2));
    if (mounted) {
      state = ItemState.data(id: id, data: "Data for $id");
    }
  }

  // A lot of methods to change the state
  // ...
  // ...
}

@freezed
class ItemState with _$ItemState {
  const factory ItemState.data({required int id, required String data}) = Data;

  const factory ItemState.loading() = Loading;

  const factory ItemState.error([String? message]) = Error;
}

flutter dart memory-leaks dispose riverpod
1个回答
1
投票

我认为这是完全可以接受的。另外,你可能没有初始值:

final itemIdProvider = Provider.autoDispose((_) => throw UnimplementedError());

这样就可以看到该值稍后会被实现。

关于记忆。

ProviderScope
是一个
StatefulWidget
,并且在“引擎盖”下有以下代码行:

@override
  void dispose() {
    container.dispose();
    super.dispose();
  }

所以你不用太担心:)

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