Riverpod 2.0 FutureProvider 的正确用法

huangapple go评论75阅读模式
英文:

Riverpod 2.0 FutureProvider correct usage

问题

我有一个字典JSON文件,我想在我的应用程序启动时加载一次,但我不确定应该如何做。我的第一种方法是这样的:

@Riverpod(keepAlive: true)
class AppDictionary extends _$AppDictionary {
  @override
  FutureOr<List<DictionaryEntry>> build() async {
    return await _parseDictionary();
  }

  Future<List<DictionaryEntry>> _parseDictionary() async {
    try {
      final response = await rootBundle.loadString('assets/dict.json');
      final data = await json.decode(response) as List<dynamic>;
      final parsedData = data
          .map((e) => DictionaryEntry.fromMap(e as Map<String, dynamic>))
          .toList();

      return parsedData;
    } catch (e) {
      print(e);
      rethrow;
    }
  }
}

在我的初始页面中,我做了这个:

final asyncDictionary = ref.watch(appDictionaryProvider);

if (asyncDictionary.isLoading) {
  return const Scaffold(
    body: Center(child: CircularProgressIndicator()),
  );
}

它运行得很好。但是在Riverpod的文档中阅读FutureProvider时,我发现我可以这样做:

@riverpod
Future<List<DictionaryEntry>> loadDictionary(LoadDictionaryRef ref) async {
  try {
    final response = await rootBundle.loadString('assets/dict.json');
    final data = await json.decode(response) as List<dynamic>;
    final parsedData = data
        .map((e) => DictionaryEntry.fromMap(e as Map<String, dynamic>))
        .toList();

    return parsedData;
  } catch (e) {
    print(e);
    rethrow;
  }
}

第二种方法也有效,所以我想知道哪种方法更好。此外,第二种方法,每次我调用ref.watch()时,它会重新加载吗?或者一旦加载了它就不会再次运行?
谢谢。

英文:

i have a dictionary JSON file that i want to load just one time when my application starts and i'm not sure about how i should do that. My first approach was doing this

@Riverpod(keepAlive: true)
class AppDictionary extends _$AppDictionary {
  @override
  FutureOr&lt;List&lt;DictionaryEntry&gt;&gt; build() async {
    return await _parseDictionary();
  }

  Future&lt;List&lt;DictionaryEntry&gt;&gt; _parseDictionary() async {
    try {
      final response = await rootBundle.loadString(&#39;assets/dict.json&#39;);
      final data = await json.decode(response) as List&lt;dynamic&gt;;
      final parsedData = data
          .map((e) =&gt; DictionaryEntry.fromMap(e as Map&lt;String, dynamic&gt;))
          .toList();

      return parsedData;
    } catch (e) {
      print(e);
      rethrow;
    }
  }
}

And in my initial page i did this

final asyncDictionary = ref.watch(appDictionaryProvider);

if (asyncDictionary.isLoading) {
  return const Scaffold(
    body: Center(child: CircularProgressIndicator()),
  );
}

And it is working fine. But reading about FutureProvider in Riverpod's documentation, i saw that i could do it this way

@riverpod
Future&lt;List&lt;DictionaryEntry&gt;&gt; loadDictionary(LoadDictionaryRef ref) async {
  try {
    final response = await rootBundle.loadString(&#39;assets/dict.json&#39;);
    final data = await json.decode(response) as List&lt;dynamic&gt;;
    final parsedData = data
        .map((e) =&gt; DictionaryEntry.fromMap(e as Map&lt;String, dynamic&gt;))
        .toList();

    return parsedData;
  } catch (e) {
    print(e);
    rethrow;
  }
}

And the second way also worked, so i'm wondering which approach is the best. Also, the second way, everytime i call ref.watch( ) will it load it again? Or once it's loaded it will not run again?
Thanks

答案1

得分: 2

第一种方式是基于类的提供程序,创建一个可见的 Notifier 子类来管理状态,并提供可能的变异方法来更新该状态。

第二种方式是基于函数的提供程序,创建一个隐藏的 Notifier 子类来管理状态,但提供放置变异方法以更新状态的地方。当通知程序基于来自其他外部输入的输入时,而不是通过方法调用来触发变异时,可以使用这种方式。不使用生成器的这种策略的示例包括 Provider、FutureProvider 和 StreamProvider。

英文:

The first way is a class-based provider, creating a visible Notifier subclass to manage the state as well as provide possible mutation methods to update that state.

The second way is a function-based provider, creating a hidden Notifier subclass to manage the state, but does not provide a place to put mutation methods to update the state. You would use this when the notifier is based on inputs from other external inputs, rather than being driven by method calls to trigger mutations. Examples of this strategy without using the generator would be Provider, FutureProvider, and StreamProvider.

huangapple
  • 本文由 发表于 2023年8月4日 03:50:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76831232.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定