Как вы создаете и изменяете поставщика логического состояния в riverpod для flutter?

#flutter #dart #riverpod

Вопрос:

Я пытаюсь создать глобального поставщика, который будет содержать логическое значение как часть семейства поставщиков

 final PaginationProvider = StateProvider.family((ref, id) => true);
 

Но мои попытки установить значение, как я сделал бы с другими поставщиками, потерпели неудачу

 context.read(PaginationProvider(0)).state = false;
 

Конкретная ошибка заключается в

 Unhandled Exception: setState() or markNeedsBuild() called during build.
This UncontrolledProviderScope widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
  UncontrolledProviderScope
The widget which was currently being built when the offending call was made was:
  Builder
 

Ответ №1:

Ну, я даже не знаю почему, но это решило проблему.

Оставляю его здесь, если у кого-то еще есть эта проблема

     Future.delayed(
        Duration.zero,
            () => context
            .read(PaginationProvider(0))
            .state = false);
 

Комментарии:

1. Причина, по которой это работает, заключается в том, что это задерживает изменение состояния на один кадр, позволяя выполнить начальную сборку до изменения состояния (что также вызывает сборку). Не откладывая этот единственный кадр, вы попадаете в бесконечный цикл перестройки.

2. @AlexHartford Это неправильный «взлом» исправления моей проблемы?

3. Нет, все в порядке. Я думаю WidgetsBinding.instance?.addPostFrameCallback , это сделало бы более очевидным, что вы делаете, но делает то же самое.