You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决自定义Capacitor Storage Hook异步返回Promise的问题

问题原因

  1. useState 不支持异步初始化函数,你传入的 async 函数会直接把 Promise 对象赋值给 state,而非 Promise resolve 后的值,这就是你的状态值显示为 [object Promise] 的核心原因。
  2. 你定义的 useCallback 没有被主动调用,状态变化后自动同步到 Storage 的逻辑完全不会触发。
  3. Hook 返回的数组没有加 as const 或者显式声明类型,TypeScript 会推断数组元素是「值类型 | 状态更新函数类型」的联合类型,所以调用 setTest 时 TS 会认为它可能不是函数,抛出 2349 错误。

修复后代码

import { useEffect, useState, Dispatch, SetStateAction } from "react";
import { Plugins } from '@capacitor/core';
import { AnyObject } from "../models/SomeModels";
const { Storage } = Plugins;

const APP_NAME = 'de.xxx.yyy';

const getStorage = async(key: string, defaultValue: string|AnyObject) => {
  const { value } = await Storage.get({
    key: `${APP_NAME}.${key}`
  });
  let returnValue;
  try {
    if (value) {
      returnValue = JSON.parse(value);
    };
  } catch(e) {
    returnValue = value;
  };
  return returnValue || defaultValue;
};

// 定义返回值类型,方便TS做类型推断
type UseStorageReturn<T> = [T, Dispatch<SetStateAction<T>>];

export const useStorage = <T extends string|AnyObject>(key: string, defaultValue: T): UseStorageReturn<T> => {
  // 先使用默认值初始化state
  const [value, setValue] = useState<T>(defaultValue);

  // 组件挂载时异步读取Storage存储的值,更新state
  useEffect(() => {
    const initStorage = async () => {
      const storedValue = await getStorage(key, defaultValue);
      setValue(storedValue);
    };
    initStorage();
  }, [key, defaultValue]);

  // 监听value变化,自动同步到Storage
  useEffect(() => {
    if (value === undefined) return;
    let newValue;
    try {
      newValue = JSON.stringify(value);
    } catch(e) {
      newValue = value;
    };
    Storage.set({
      key: `${APP_NAME}.${key}`,
      value: newValue as string
    });
  }, [key, value]);

  // 加as const固定返回值的元组类型,避免TS推断为联合类型
  return [value, setValue] as const;
};

可选优化

如果需要避免默认值到存储值的切换闪烁,可以在 Hook 里新增一个 isLoading 状态,读取 Storage 完成前渲染加载占位态即可。

内容的提问来源于stack exchange,提问作者csaar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:24:04