Flutter Hooks 和异步调用

问题描述

一些菜鸟问题。

我在我的应用中使用 Flutter Hooks,但在尝试使用带有异步调用的钩子时很挣扎。

例如,如何通过 useMemoized(或任何其他带有钩子的异步数据)获取 SharedPreferences?

SharedPreferences preferences = useMemoized(() async => await SharedPreferences.getInstance());

上面的代码不起作用,因为“无法将参数类型‘Future Function()’分配给参数类型‘SharedPreferences Function()’。”,但如何完成?

我希望存储 SharedPreferences 实例以用于读取和写入值。


下面展示了我如何完成工作的真实示例,但我想知道是否有更好的方法。

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:location/location.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LocationWidget extends HookWidget {
  const LocationWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final Location location = useMemoized(() => Location());
    final ValueNotifier<bool> isLocationEnabled = useState(false);
    final ValueNotifier<bool> isServiceEnabled = useState(false);
    final ValueNotifier<PermissionStatus> permissionStatus = useState(PermissionStatus.denied);

    useEffect(() {
      Future<void>.microtask(() async {
        final SharedPreferences preferences = await SharedPreferences.getInstance();
        isLocationEnabled.value = preferences.getBool('trackingEnabled') ?? false;

        isServiceEnabled.value = await location.serviceEnabled();
        permissionStatus.value = await location.hasPermission();
      });
    },<Location>[location]);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
        Text(
          'Location',style: Theme.of(context).textTheme.headline6,),const SizedBox(height: 5.0),Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[
            const Text('Tracking service'),Switch(
              value: isLocationEnabled.value,activeTrackColor: Colors.amberAccent,activeColor: Colors.amber,onChanged: (bool value) async {
                if (value) {
                  if (permissionStatus.value == PermissionStatus.denied) {
                    permissionStatus.value = await location.requestPermission();
                  }

                  if (permissionStatus.value == PermissionStatus.granted) {
                    if (!isServiceEnabled.value) {
                      isServiceEnabled.value = await location.requestService();
                    }

                    value = isServiceEnabled.value ? value : !value;
                  }
                }

                final SharedPreferences preferences = await SharedPreferences.getInstance();
                preferences.setBool('trackingEnabled',value);

                isLocationEnabled.value = value;
              },],);
  }
}

解决方法

我认为您当前的代码已经足够了,但如果您想使用 useMemoized,我建议这样做。

final future = useMemoized(SharedPreferences.getInstance);
final snapshot = useFuture(future,initialData: null);

useEffect(() {
  final preferences = snapshot.data;
  if (preferences == null) {
    return;
  }
  preferences.getBool('');
},[snapshot.data]);

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...