fix: load collabora config without stuck fetcher state

This commit is contained in:
wren
2026-05-06 17:44:32 +08:00
parent f758acaa18
commit 5405d30111
+57 -24
View File
@@ -9,7 +9,6 @@
* @encoding UTF-8 * @encoding UTF-8
*/ */
import { useFetcher } from '@remix-run/react';
import { RefObject, useCallback, useEffect, useMemo, useState } from 'react'; import { RefObject, useCallback, useEffect, useMemo, useState } from 'react';
import { COLLABORA_URL } from '~/config/api-config'; import { COLLABORA_URL } from '~/config/api-config';
import { toastService } from '../ui/Toast'; import { toastService } from '../ui/Toast';
@@ -35,37 +34,71 @@ export function useCollaboraConfig(
userId: string, userId: string,
userName: string userName: string
) { ) {
const fetcher = useFetcher<CollaboraConfig>(); const [config, setConfig] = useState<CollaboraConfig | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
if (fetcher.state === 'idle' && !fetcher.data) { if (!fileId) {
// 构建查询参数 setConfig(null);
const params = new URLSearchParams({ setError('文件路径不能为空');
fileId, setLoading(false);
mode, return;
userId,
userName,
});
// 加载配置
fetcher.load(`/api/collabora/config?${params}`);
} }
}, [fileId, mode, userId, userName, fetcher]);
// 检查错误 const controller = new AbortController();
useEffect(() => { const params = new URLSearchParams({
if (fetcher.data && 'error' in fetcher.data) { fileId,
const errorData = fetcher.data as { error: string }; mode,
const errorMessage = errorData.error || '加载配置失败'; userId,
setError(errorMessage); userName,
toastService.error(`加载文档配置失败: ${errorMessage}`); });
async function loadConfig() {
setLoading(true);
setError(null);
setConfig(null);
try {
const response = await fetch(`/api/collabora/config?${params}`, {
method: 'GET',
signal: controller.signal,
headers: {
Accept: 'application/json',
},
});
const result = (await response.json()) as CollaboraConfig | { error?: string };
if (!response.ok || ('error' in result && result.error)) {
const errorMessage =
('error' in result && result.error) || `加载配置失败 (${response.status})`;
setError(errorMessage);
toastService.error(`加载文档配置失败: ${errorMessage}`);
return;
}
setConfig(result as CollaboraConfig);
} catch (err) {
if (controller.signal.aborted) return;
const errorMessage = err instanceof Error ? err.message : '加载配置失败';
setError(errorMessage);
toastService.error(`加载文档配置失败: ${errorMessage}`);
} finally {
if (!controller.signal.aborted) {
setLoading(false);
}
}
} }
}, [fetcher.data]);
void loadConfig();
return () => controller.abort();
}, [fileId, mode, userId, userName]);
return { return {
config: fetcher.data && !('error' in fetcher.data) ? fetcher.data : null, config,
loading: fetcher.state === 'loading', loading,
error, error,
}; };
} }