forked from 77media/video-flow
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import { useCallback, useEffect } from 'react';
|
||
import { useAppDispatch, useAppSelector } from './hooks';
|
||
import { setError, setLoading, setValue } from './serverSettingSlice';
|
||
import { fetchSettingByCode } from '@/api/serversetting';
|
||
|
||
/**
|
||
* 使用服务端配置(按 code)
|
||
* - 自动拉取并存入 store
|
||
* - 返回 loading/error/value 状态
|
||
*/
|
||
export function useServerSetting<T = unknown>(code: string, defaultValue?: T) {
|
||
const dispatch = useAppDispatch();
|
||
const entry = useAppSelector((s) => s.serverSetting.byCode[code]);
|
||
|
||
const load = useCallback(async () => {
|
||
if (!code) return;
|
||
dispatch(setLoading({ code, loading: true }));
|
||
try {
|
||
const value = await fetchSettingByCode<T>(code, defaultValue as T | undefined);
|
||
dispatch(setValue<T>({ code, value: value as T }));
|
||
} catch (e: any) {
|
||
dispatch(setError({ code, error: e?.message || 'Load failed' }));
|
||
}
|
||
}, [code, defaultValue, dispatch]);
|
||
|
||
useEffect(() => {
|
||
// 仅当未加载过或无值时加载
|
||
if (!entry || (entry && entry.value === undefined && !entry.loading)) {
|
||
load();
|
||
}
|
||
}, [entry, load]);
|
||
|
||
return {
|
||
loading: entry?.loading ?? false,
|
||
error: entry?.error,
|
||
value: (entry?.value as T | undefined) ?? defaultValue,
|
||
reload: load,
|
||
} as const;
|
||
}
|
||
|
||
|