Riverpod: альтернативный способ переопределения initState внутри ConsumerWidget

Каково решение инициализации вещей внутри consumerWidget, поскольку метод initState здесь не может быть переопределен?


person towhid    schedule 04.10.2020    source источник


Ответы (3)


Обновлено

Из Riverpod v1.0.0-dev.2

Вы можете использовать ConsumerStatefulWidget и ConsumerState

final helloWorldProvider = Provider((_) => 'Hello world');

class RiverpodExample extends ConsumerStatefulWidget {
  @override
 _RiverpodExampleState createState() => _RiverpodExampleState();
}

class _RiverpodExampleState extends ConsumerState<Example> {

  @override
  void initState() {
    super.initState();

    final value = ref.read(helloWorldProvider);

  }

  @override
  Widget build(BuildContext context) {
    final value = ref.watch(helloWorldProvider);

    return Text(value); // Hello world
  }
}

или добавьте ConsumerStateMixin миксин в свой класс StatefulWidget

class StatefulExample extends StatefulWidget {
  @override
  _StatefulExampleState createState() => _StatefulExampleState();
}

class _StatefulExampleState extends State<StatefulExample> with ConsumerStateMixin {
  void initState() {
    super.initState();

    // You can access WidgetReference (ref)
    final value = ref.read(helloWorldProvider);

  }

  @override
  Widget build(BuildContext context) {
    A value = ref.watch(a);
    
    return Container();
  }
}

Взгляните на эту проблему - https://github.com/rrousselGit/river_pod/issues/335


До Riverpod v0.14.0 + 3

Вы должны использовать StatefulWidget и вернуть Consumer в качестве корневого виджета. из метода build.

Потребитель

Consumer можно использовать для прослушивания поставщиков внутри StatefulWidget или для восстановления как можно меньшего количества виджетов при обновлении поставщика.

final helloWorldProvider = Provider((_) => 'Hello world');

class RiverpodExample extends StatefulWidget {
  @override
  _RiverpodExampleState createState() => _RiverpodExampleState();
}

class _RiverpodExampleState extends State<Example> {

  @override
  void initState() {
    super.initState();

  }

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, watch, child) {
        final value = watch(helloWorldProvider);
        return Text(value); // Hello world
      },
    );
  }
}
person Vinoth Vino    schedule 06.10.2020
comment
Да, это могло бы быть решением, но он полностью упускает из виду мощь Riverpod / ConsumerWidget. - person towhid; 06.10.2020
comment
Я пока не думаю по-другому @towhid - person Vinoth Vino; 06.10.2020

Я не совсем уверен, как ответить на ваш вопрос, поскольку я не работал с ConsumerWidget. Я предполагаю, что идея состоит в том, чтобы сохранить большую часть вашего состояния в провайдерах.

Однако я хотел бы порекомендовать использовать hooks_riverpod вместе с flutter_hooks (тот же разработчик).

Это упрощает сохранение локального состояния виджета, а также обеспечивает легкий доступ к поставщикам.

Например:

class Example extends HookWidget {
  const Example({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final test = useProvider(Test.provider());

    final controller = useTextEditingController();
    final loading = useState(false);
    final buttonText = useState('Change me!');

    return Column(
      children: [
        TextField(controller: controller),
        if (!loading) RaisedButton(
          onPressed: () async {
            loading.value = true;
            await Future.delayed(const Duration(seconds: 1));
            buttonText.value = controller.text;
            loading.value = false;
          }
          child: Text(buttonText.value),
        ),
        if (loading) const CircularProgressIndicator(),
        // Do something with providers, etc.
      ],
    ),
  );
}

Просто быстрый пример, но ресурсов много (flutter_hooks, hooks_riverpod), чтобы помочь вам. Также ознакомьтесь с примерами от разработчика использования крючков Riverpod.

person Alex Hartford    schedule 05.10.2020
comment
Написав свой код, руководствуясь вашим ответом, я могу сделать вывод, что это правильный способ реализовать flutter_hooks с помощью hook_riverpod и установить переменные при запуске виджета (и это в документации). Это потому, что начальные значения не перезаписывают то, что вы могли установить или обновить в возвращенном виджете, даже если вы его перестроили, поэтому это точно так же, как при использовании initState. - person José Luna; 06.12.2020

Возможно, я опоздаю, но с выходом Riverpod 1.0.0 вы сможете использовать https://pub.dev/documentation/flutter_riverpod/1.0.0-dev.2/flutter_riverpod/ConsumerStatefulWidget-class.html и https://pub.dev/documentation/flutter_riverpod/1.0.0-dev.2/flutter_riverpod/ConsumerState-class.html, который делает именно то, что вы хотите.

person wujek    schedule 02.07.2021