【问题标题】:Flutter changing Text value using RiverPod State management使用 RiverPod 状态管理 Flutter 更改 Text 值
【发布时间】:2021-01-28 03:46:59
【问题描述】:

在下面的代码中,我编写了简单的代码来更改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.
      ),
    );
  }
}

【问题讨论】:

    标签: flutter riverpod


    【解决方案1】:

    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+ 的更多信息,请访问 here


    以下内容包含问题的原始答案。仅对 riverpod 有效。

    变化:

    final s = watch(showHello).state;
    

    到:

    final s = watch(showHello.state);
    

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

    此概念扩展到其他类型的提供程序,例如listening to the last exposed value of a StreamProvider.

    A similar question I answered in the past.

    【讨论】:

    • 不客气。如果您有兴趣,我更新了我的答案,解释了为什么存在这种行为。
    • 我已经更新了最新 Riverpod 0.14.0+ 语法的示例。
    • 能不能把状态本身和状态控制器的区别加一下(如果我们想修改状态本身就需要注意)?
    • @SalahAdDin 使用 StateNotifier 时,您不会从 StateNotifier 类本身之外更新状态。你是在引用 StateProvider 吗?
    • 是的,StateProvider。
    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 2022-09-24
    • 2021-11-27
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    相关资源
    最近更新 更多