【问题标题】:Flutter riverpod state does not changeFlutter Riverpod 状态不变
【发布时间】:2022-09-27 20:57:00
【问题描述】:

我尝试在我自己的类中使用 StateNotifier,但无论我做什么,状态都不会改变。我使用的是 Riverpod 版本 ^1.0.4。当我在我的 StateNotifier 中执行一个函数时,函数中的状态会发生变化,但在 UI 部分,它不会改变。状态始终保持 ListInit。但我不知道为什么。我打印了状态运行时类型,在函数中,它发生了变化,但在 UI 部分中没有。我在另一个带有 Riverpod 版本 ^0.14.0+3 的项目中使用了相同的结构,它在那里工作(我将版本 ^1.0.4 的新更改添加到我的代码中)。我不知道我想念什么。我检查了几次代码,但一无所获。而且我也没有收到错误。我错过了什么吗?

import \'package:finanz_app/models/konten.dart\';
import \'package:flutter_riverpod/flutter_riverpod.dart\';
import \'package:hive_flutter/hive_flutter.dart\';

abstract class ListState {
  const ListState();
}

class ListInit extends ListState {
  const ListInit();
}

class ListLoding extends ListState {
  const ListLoding();
}

class ListLoded extends ListState {
  final List<Konten> konten;
  const ListLoded(this.konten);
}

class ListError extends ListState {
  final String errorMessage;
  const ListError(this.errorMessage);
}

final listNotifierProvider = StateNotifierProvider((ref) {
  return ListStateNotifier();
});

class ListStateNotifier extends StateNotifier<ListState> {
  ListStateNotifier() : super(const ListInit());

  Future<void> getFromDB() async {
    state = const ListLoding();

    final box = Hive.box(\'konten\');

    final List<Konten> kontenData = box.keys.map((key) {
      final Konten value = box.get(key);
      return value;
    }).toList();

    print(kontenData.length);
    state = ListLoded(kontenData);

    print(state.runtimeType);
  }

  Future<void> add(Konten konto) async {
    final box = Hive.box(\'konten\');

    box.add(konto);

    print(state.runtimeType);

    getFromDB();
  }

  Future<void> deletedAll() async {
    final box = Hive.box(\'konten\');

    for (int key in box.keys) {
      box.delete(key);
    }

    getFromDB();
  }
}


...
body:
  Consumer(
    builder: (context, ref, child) {
      final state = ref.watch(listNotifierProvider);

      print(state.runtimeType);

      if (state is ListInit) {
        return const Text(
          \"InitState\",
        );
      } else if (state is ListLoding) {
        return const CircularProgressIndicator();
      } else if (state is ListLoded) {
        return Text(state.konten.length.toString());

      } else if (state is ListError) {
        return Text(\"ERROR: ${state.errorMessage}\");
      } else {
        return const Text(\"Unknown ERROR\");
      }
    },
  ),
...

@override
  Widget build(BuildContext context) {
    return ProviderScope(
      child: MaterialApp(
        ...
        initialRoute: \'/\',
        routes: {
          \"/\": (context) => const HomePage(),
        },
      ),
    );
  }
  • 状态可能没有改变。您需要确保新状态是新对象,而不是现有状态的变异版本。

标签: flutter dart state riverpod flutter-riverpod


【解决方案1】:

问题是我们需要确保新状态是一个新对象。状态也不能是可变对象。

您可能会尝试使用“联合类型”/“密封类”/模式匹配等功能。 使用 freezed 库,很容易做到这一点:

@freezed
class ListState with _$ListState {
  const factory ListState.init() = Init;
  const factory ListState.loading() = Loading;
  const factory ListState.loaded(List<Konten> konten) = Loaded;
  const factory ListState.error(String? errorMessage) = Error;
}

在 build 方法内部看起来像这样:

final ListState state = ref.watch(listNotifierProvider);

print(
  state.when(
    init: () => 'init',
    loading: () => 'loading',
    loaded: (List<Konten> konten) => 'loaded',
    error: (String? errorMessage) => 'Error: $message',
  ),
);

【讨论】:

    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2021-01-28
    相关资源
    最近更新 更多