Riverpod:在 ConsumerWidget 中覆盖 initState 的替代方法

tow*_*hid 8 provider dart flutter riverpod

由于 initState 方法在此处不可覆盖,因此在 consumerWidget 内部初始化事物的解决方案是什么?

Vin*_*ino 14

更新

来自Riverpod v1.0.0-dev.2

您可以使用ConsumerStatefulWidgetConsumerState

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
  }
}
Run Code Online (Sandbox Code Playgroud)

或将ConsumerStateMixinmixin添加到您的 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

看看这个问题 - https://github.com/rrousselGit/river_pod/issues/335


更新至 Riverpod v0.14.0+3

您必须使用StatefulWidget并返回Consumer作为方法的根小部件build

消费者

消费者可用于侦听 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
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案需要注意的重要部分是“initState”中有“read”,“build”中有“watch”。`Watch` 在 `initState` 中不起作用。 (4认同)

Ale*_*ord 5

我不完全确定如何回答你的问题,因为我没有使用过 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.
      ],
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

只是一个简单的例子,但有大量的资源(flutter_hookshooks_riverpod)可以帮助您。另外,请查看开发人员提供的关于 Riverpod Hooks 使用的示例。

  • 在根据您的答案编写代码后,我可以得出结论,这是使用 hook_riverpod 实现 flutter_hooks 并在小部件启动时设置变量的正确方法(并且在文档中)。这是因为即使您重建了返回的小部件,初始值也不会覆盖您可以在返回的小部件中设置或更新的内容,因此它与使用 initState 完全相同。 (3认同)