用于电容器存储的自定义挂钩
Custom hook for Capacitor storage
我正在尝试实现一个自定义挂钩,它通过自动将当前状态值保存在电容器存储中来扩展 useState()。
在这种情况下,我正在努力使用 Capacitor 存储插件的同步功能,这导致我的“自定义状态”实际上是一个承诺:/
有什么办法可以解决这个问题吗?我已经尝试将 value
初始化为未定义状态,并通过确定初始值来扩展 useCallback。但这没有用。
自定义挂钩:
import { useCallback, useState } 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;
};
export const useStorage = (key: string, defaultValue: string|AnyObject) => {
const [value, setValue] = useState<string|AnyObject>(async() => await getStorage(key, defaultValue));
useCallback(() => {
if (value) {
let newValue;
try {
newValue = JSON.stringify(value);
} catch(e) {
newValue = value;
};
Storage.set({
key: `${APP_NAME}.${key}`,
value: newValue as string
});
};
}, [key, value]);
return [value, setValue];
};
组件:
[...]
const [test, setTest] = useStorage('Test', '1');
[...]
return (
[...]
<IonItem>
<IonLabel>Test</IonLabel>
<IonInput value={test as string} />
</IonItem>
[...]
结果:
我从 this blog 得到了这个钩子的想法。
编辑:
通过为 IonInput 添加更改处理程序 (onIonChange={e => setTest(e.detail.value!)}
),我发现 setTest
也不起作用。
Dieser Ausdruck kann nicht aufgerufen werden.
Es ist kein Bestandteil vom Typ "string | AnyObject" aufrufbar.ts(2349)
const setTest: string | AnyObject
想了又想,午饭后终于搞定了。
我必须将 value
初始化为空状态,将 useCallback 更改为 useEffect 并将空案例添加到我的条件中。
也许有人可以解释,为什么我必须在最后设置 as const
?
import { useEffect, useState } 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;
};
export const useStorage = (key: string, defaultValue: string|AnyObject) => {
const [value, setValue] = useState<string|AnyObject>();
useEffect(() => {
if (value || typeof value === 'string') {
let newValue;
try {
newValue = JSON.stringify(value);
} catch(e) {
newValue = value;
};
Storage.set({
key: `${APP_NAME}.${key}`,
value: newValue as string
});
} else {
getStorage(key, defaultValue).then(v => setValue(v));
};
}, [key, value, defaultValue]);
return [value, setValue] as const;
};
我正在尝试实现一个自定义挂钩,它通过自动将当前状态值保存在电容器存储中来扩展 useState()。
在这种情况下,我正在努力使用 Capacitor 存储插件的同步功能,这导致我的“自定义状态”实际上是一个承诺:/
有什么办法可以解决这个问题吗?我已经尝试将 value
初始化为未定义状态,并通过确定初始值来扩展 useCallback。但这没有用。
自定义挂钩:
import { useCallback, useState } 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;
};
export const useStorage = (key: string, defaultValue: string|AnyObject) => {
const [value, setValue] = useState<string|AnyObject>(async() => await getStorage(key, defaultValue));
useCallback(() => {
if (value) {
let newValue;
try {
newValue = JSON.stringify(value);
} catch(e) {
newValue = value;
};
Storage.set({
key: `${APP_NAME}.${key}`,
value: newValue as string
});
};
}, [key, value]);
return [value, setValue];
};
组件:
[...]
const [test, setTest] = useStorage('Test', '1');
[...]
return (
[...]
<IonItem>
<IonLabel>Test</IonLabel>
<IonInput value={test as string} />
</IonItem>
[...]
结果:
我从 this blog 得到了这个钩子的想法。
编辑:
通过为 IonInput 添加更改处理程序 (onIonChange={e => setTest(e.detail.value!)}
),我发现 setTest
也不起作用。
Dieser Ausdruck kann nicht aufgerufen werden. Es ist kein Bestandteil vom Typ "string | AnyObject" aufrufbar.ts(2349)
const setTest: string | AnyObject
想了又想,午饭后终于搞定了。
我必须将 value
初始化为空状态,将 useCallback 更改为 useEffect 并将空案例添加到我的条件中。
也许有人可以解释,为什么我必须在最后设置 as const
?
import { useEffect, useState } 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;
};
export const useStorage = (key: string, defaultValue: string|AnyObject) => {
const [value, setValue] = useState<string|AnyObject>();
useEffect(() => {
if (value || typeof value === 'string') {
let newValue;
try {
newValue = JSON.stringify(value);
} catch(e) {
newValue = value;
};
Storage.set({
key: `${APP_NAME}.${key}`,
value: newValue as string
});
} else {
getStorage(key, defaultValue).then(v => setValue(v));
};
}, [key, value, defaultValue]);
return [value, setValue] as const;
};