4

在下面的代码中,我制作了简单的代码来更改Text小部件字符串,默认字符串可以显示到Text小部件中,但是当我尝试单击时FloatingActionButton不会更改。

单击HotReload原因将其更改为新值,我应该在哪里更改以解决此问题?

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/all.dart';


class MyString extends StateNotifier<String> {
  MyString() : super('Hello World');

  void change(String text) => state = text;
}

final showHello = StateNotifierProvider<MyString>((ref) => MyString());

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('SAMPLE'),
        ),
        body: Center(
          child: Consumer(
            builder: (context, watch, _) {
              final s = watch(showHello).state;
              return Text(s);
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => context.read(showHello).change('Clicked On Button'),
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ), // This trailing comma makes auto-formatting nicer for build methods.
      ),
    );
  }
}
4

1 回答 1

5

2021 年 4 月更新:从 Riverpod >= 0.14.0 开始,语法现已更新(向下滚动查看原始答案)。下面演示了如何将问题中提供的示例代码转换为更新的语法:

import 'package:flutter/material.dart';
// Note importing hooks_riverpod/all.dart is now deprecated
import 'package:hooks_riverpod/hooks_riverpod.dart';


class MyString extends StateNotifier<String> {
  MyString() : super('Hello World');

  void change(String text) => state = text;
}

// Note the extra parameter, String, to specify what is provided by the Notifier
final showHello = StateNotifierProvider<MyString, String>((ref) => MyString());

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('SAMPLE'),
        ),
        body: Center(
          child: Consumer(
            builder: (context, watch, _) {
              // Note here, state does not need to be specified.
              final s = watch(showHello);
              return Text(s);
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // Note that we now specify notifier here to access non-state
            // attributes of the Notifier
            context.read(showHello.notifier).change('Clicked On Button');
          },
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

更多关于升级到 Riverpod 0.14.0+ 的信息可以在这里找到。


以下包含问题的原始答案。它仅对riverpod <= 0.13有效。

改变:

final s = watch(showHello).state;

到:

final s = watch(showHello.state);

这种行为的原因是您正在查看通知程序本身,而不是其状态。由于通知对象实际上并没有被更改,只是状态属性,因此不会触发重建(这就是您在热重载时看到更新的原因)。通过观察状态本身,我们在状态改变时重建。

这个概念扩展到其他类型的提供者,例如监听 StreamProvider 的最后公开值

我过去回答过一个类似的问题。

于 2020-10-13T19:48:12.457 回答