fix: caching and reactivity
This commit is contained in:
+19
-25
@@ -1,4 +1,4 @@
|
||||
import { Component, createSignal, onMount, onCleanup, Show } from 'solid-js';
|
||||
import { Component, createSignal, createEffect, onCleanup, Show, createResource } from 'solid-js';
|
||||
import { parseMarkdown } from '../markdown';
|
||||
import { fetchData, extractSection } from '../data-loader';
|
||||
|
||||
@@ -9,51 +9,45 @@ export interface ArticleProps {
|
||||
onError?: (error: Error) => void;
|
||||
}
|
||||
|
||||
async function fetchArticleContent(params: { src: string; section?: string }): Promise<string> {
|
||||
const text = await fetchData(params.src);
|
||||
// 如果指定了 section,提取对应内容
|
||||
return params.section ? extractSection(text, params.section) : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Article 组件
|
||||
* 用于将特定 src 位置的 md 文件显示为 markdown 文章
|
||||
*/
|
||||
export const Article: Component<ArticleProps> = (props) => {
|
||||
const [content, setContent] = createSignal('');
|
||||
const [loading, setLoading] = createSignal(true);
|
||||
const [error, setError] = createSignal<Error | null>(null);
|
||||
const [content, { refetch }] = createResource(
|
||||
() => ({ src: props.src, section: props.section }),
|
||||
fetchArticleContent
|
||||
);
|
||||
|
||||
let articleRef: HTMLArticleElement | undefined;
|
||||
|
||||
onMount(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const text = await fetchData(props.src);
|
||||
// 如果指定了 section,提取对应内容
|
||||
const finalContent = props.section
|
||||
? extractSection(text, props.section)
|
||||
: text;
|
||||
setContent(finalContent);
|
||||
setLoading(false);
|
||||
createEffect(() => {
|
||||
const data = content();
|
||||
if (data) {
|
||||
props.onLoaded?.();
|
||||
} catch (err) {
|
||||
const errorObj = err instanceof Error ? err : new Error(String(err));
|
||||
setError(errorObj);
|
||||
setLoading(false);
|
||||
props.onError?.(errorObj);
|
||||
}
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
// 清理时清空内容,触发内部组件的销毁
|
||||
setContent('');
|
||||
});
|
||||
|
||||
return (
|
||||
<article ref={articleRef} class="prose" data-src={props.src}>
|
||||
<Show when={loading()}>
|
||||
<Show when={content.loading}>
|
||||
<div class="text-gray-500">加载中...</div>
|
||||
</Show>
|
||||
<Show when={error()}>
|
||||
<div class="text-red-500">加载失败:{error()?.message}</div>
|
||||
<Show when={content.error}>
|
||||
<div class="text-red-500">加载失败:{content.error?.message}</div>
|
||||
</Show>
|
||||
<Show when={!loading() && !error()}>
|
||||
<div innerHTML={parseMarkdown(content())} />
|
||||
<Show when={!content.loading && !content.error && content()}>
|
||||
<div innerHTML={parseMarkdown(content()!)} />
|
||||
</Show>
|
||||
</article>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user