refactor: 收敛渲染链路共享抽象
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import type { RenderedMarkdownDocument } from "@md-to-pdf/core";
|
||||
|
||||
export interface MarkdownRenderCallbacks {
|
||||
onRenderStart?: () => void;
|
||||
onStatusChange?: (status: string) => void;
|
||||
}
|
||||
|
||||
export function useMarkdownRender(
|
||||
markdown: string,
|
||||
language: string,
|
||||
callbacks: MarkdownRenderCallbacks = {}
|
||||
) {
|
||||
const [result, setResult] =
|
||||
useState<RenderedMarkdownDocument | null>(null);
|
||||
const [error, setError] = useState("");
|
||||
const { onRenderStart, onStatusChange } = callbacks;
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const timer = window.setTimeout(() => {
|
||||
onStatusChange?.("正在渲染…");
|
||||
onRenderStart?.();
|
||||
setError("");
|
||||
|
||||
void fetch("/api/render", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({ markdown, language }),
|
||||
signal: controller.signal
|
||||
})
|
||||
.then(async (response) => {
|
||||
const payload = (await response.json()) as
|
||||
| RenderedMarkdownDocument
|
||||
| { message?: string };
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
"message" in payload
|
||||
? payload.message ?? "渲染失败"
|
||||
: "渲染失败"
|
||||
);
|
||||
}
|
||||
return payload as RenderedMarkdownDocument;
|
||||
})
|
||||
.then((payload) => {
|
||||
setResult(payload);
|
||||
onStatusChange?.("预览已更新");
|
||||
})
|
||||
.catch((reason: unknown) => {
|
||||
if (!controller.signal.aborted) {
|
||||
setError(
|
||||
reason instanceof Error ? reason.message : "渲染失败"
|
||||
);
|
||||
onStatusChange?.("预览失败");
|
||||
}
|
||||
});
|
||||
}, 250);
|
||||
|
||||
return () => {
|
||||
window.clearTimeout(timer);
|
||||
controller.abort();
|
||||
};
|
||||
}, [language, markdown, onRenderStart, onStatusChange]);
|
||||
|
||||
return { error, result };
|
||||
}
|
||||
Reference in New Issue
Block a user