flutter RiverPod 2.0家庭提供程序正在重置状态而不是更新

jjjwad0x  于 2023-05-19  发布在  Flutter
关注(0)|答案(1)|浏览(123)

我不知道为什么我的提供程序每次更新状态时都调用build。
本质上,我调用controller.createVoice,然后应该创建一个带有id的语音,并将其附加到selectedIds,但出于某种原因,它不是。我怀疑这与build被调用以及我实际上是如何构建东西有关。

class _EditTopicScreenState extends ConsumerState<EditTopicScreen> {
  @override
  Widget build(BuildContext context) {
    final controller =
        ref.read(editTopicControllerProvider(topicId: widget.topicId).notifier);
    final state =
        ref.watch(editTopicControllerProvider(topicId: widget.topicId));
    final topicNameFieldController =
        TextEditingController(text: controller.name);
    return FlutterDataWidget<Topic?>(
        findRequest: ref.topics.findOne(widget.topicId, remote: false),
        child: (topic) {
          return Drawer(
                // ...
                ),
                body: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Column(
                    children: [
                      ...
                      VoiceCreatorV2(
                        onAdd: (name) => controller.createVoice(name),
                      ),
                      const SizedBox(height: 20),
                      Flexible(
                        child: VoicesSelectV2(
                          selectedVoiceIds: state.selectedIds,
                          onAdd: (voiceId) => controller.addVoice(voiceId),
                          onRemove: (voiceId) =>
                              controller.removeVoice(voiceId),
                        ),
                      ),
                      // ...
                    ],
                  ),
                ),
              ));
        });
  }
}

Riverpod代码在这里,我用的是2.0

@riverpod
class EditTopicController extends _$EditTopicController {
  @override
  EditTopicControllerState build({required String topicId}) {
    final voices = ref.voices.watchAll(remote: false).model;
    final activeVoices = voices?.where((v) => v.archivedAt == null).toList() ??
        []; // Used for sorting voices on load so the ones selected are first
    final topic = ref.topics.watchOne(topicId, remote: false).model;
    final selectedIds =
        topic?.voices.toList().map((e) => e.id!).toList() ?? [] as List<String>;

    final List<Voice> sortedVoices = [
      ...activeVoices.where((v) => selectedIds.contains(v.id)).toList(),
      ...activeVoices.where((v) => !selectedIds.contains(v.id)).toList()
    ]; // Used for sorting voices on load so the ones selected are first

    return EditTopicControllerState(
        name: topic?.name ?? '',
        selectedIds: selectedIds,
        sortedVoices: sortedVoices);
  }

  List<String> get selectedIds => state.selectedIds;
  String get name => state.name;
  void updateTopicName(String name) {
    state = state.copyWith(name: name);
  }

  void addVoice(String id) {
    state = state.copyWith(selectedIds: [...state.selectedIds, id]);
  }

 //...

  void createVoice(String name) async {
    // used voice model to create voice
    final voice = await Voice.newVoice(
      name: name,
      color: HexColorParser().generateRandomHexColor(),
    ).save(remote: true);
    addVoice(voice.id!);
  }
//...
}

坦白地说,我不确定这是否是处理这样的事情的正确方法,也许我错过了一个关键的概念,所以如果我是,让我知道。
我希望这是所有需要得到帮助的!
先谢谢你了

yr9zkbsy

yr9zkbsy1#

这条线就是罪魁祸首final voices = ref.voices.watchAll(remote: false).model;
好吧,原来问题出在供应商身上。我在观察所有的声音,因为我在观察它们,当我创造一个新的声音时,它完全重建,由于它被观察,从而消除了我的状态。

相关问题