如何解决自定义Capacitor Storage Hook异步返回Promise的问题
问题原因
useState不支持异步初始化函数,你传入的 async 函数会直接把 Promise 对象赋值给 state,而非 Promise resolve 后的值,这就是你的状态值显示为[object Promise]的核心原因。- 你定义的
useCallback没有被主动调用,状态变化后自动同步到 Storage 的逻辑完全不会触发。 - 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
相关产品推荐
相关产品推荐

