【问题标题】:Flutter Hooks and async callsFlutter Hooks 和异步调用
【发布时间】:2021-04-03 22:43:57
【问题描述】:

前面有一些菜鸟问题。

我在我的应用程序中使用 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;
              },
            ),
          ],
        ),
      ],
    );
  }
}

【问题讨论】:

    标签: flutter flutter-hooks


    【解决方案1】:

    我认为您当前的代码已经足够了,但是如果您想使用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]);
    

    【讨论】:

    • 感谢您的回答。但是,并不是我要使用 useMemoized,而是解决此类情况的最佳方法:钩子 x 异步调用。您认为哪种方法最好?
    • @MarcusM。如前所述,您当前的方法就足够了。我正在使用useAsyncEffect 为您的微任务使用。 SharedPreferences 在内部缓存实例,因此不考虑性能。我没有看到更好的方法。
    • 知道了,感谢 useAsyncEffect 提示?。
    • 当我这样做时,我不知道为什么会弹出一个空安全问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2018-09-30
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多