资源与异步 #
一、createResource 概述 #
1.1 什么是 Resource #
createResource 是 Solid 提供的异步数据获取原语,用于管理 API 请求等异步操作。
jsx
import { createResource } from 'solid-js';
function UserProfile({ userId }) {
const [user] = createResource(userId, fetchUser);
return (
<Show when={user()} fallback={<p>Loading...</p>}>
{(data) => <h1>{data().name}</h1>}
</Show>
);
}
1.2 Resource 状态 #
| 属性 | 说明 |
|---|---|
loading |
是否正在加载 |
error |
错误信息 |
() |
数据值 |
latest |
最新值(不触发 Suspense) |
二、基本用法 #
2.1 简单请求 #
jsx
async function fetchUsers() {
const response = await fetch('/api/users');
return response.json();
}
function UserList() {
const [users] = createResource(fetchUsers);
return (
<Show when={!users.loading} fallback={<p>Loading...</p>}>
<ul>
<For each={users()}>
{(user) => <li>{user.name}</li>}
</For>
</ul>
</Show>
);
}
2.2 响应式参数 #
jsx
function UserProfile() {
const [userId, setUserId] = createSignal(1);
const [user] = createResource(userId, async (id) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
});
return (
<div>
<button onClick={() => setUserId(prev => prev + 1)}>
Next User
</button>
<Show when={user()} fallback={<p>Loading...</p>}>
{(data) => <h1>{data().name}</h1>}
</Show>
</div>
);
}
2.3 使用 Suspense #
jsx
import { Suspense } from 'solid-js';
function App() {
return (
<Suspense fallback={<p>Loading...</p>}>
<UserProfile />
</Suspense>
);
}
三、错误处理 #
3.1 错误状态 #
jsx
function DataFetcher() {
const [data] = createResource(fetchData);
return (
<Switch>
<Match when={data.error}>
<div class="error">
<p>Failed to load data</p>
<button onClick={data.refetch}>Retry</button>
</div>
</Match>
<Match when={data.loading}>
<p>Loading...</p>
</Match>
<Match when={data()}>
{(d) => <DataDisplay data={d()} />}
</Match>
</Switch>
);
}
3.2 ErrorBoundary #
jsx
import { ErrorBoundary } from 'solid-js';
function App() {
return (
<ErrorBoundary fallback={(err) => (
<div>
<h2>Something went wrong</h2>
<p>{err.message}</p>
</div>
)}>
<DataComponent />
</ErrorBoundary>
);
}
四、手动控制 #
4.1 mutate 方法 #
jsx
function OptimisticUpdate() {
const [todos, { mutate, refetch }] = createResource(fetchTodos);
const addTodo = async (text) => {
mutate(prev => [...prev, { id: Date.now(), text }]);
await fetch('/api/todos', { method: 'POST', body: JSON.stringify({ text }) });
refetch();
};
return (
<div>
<button onClick={() => addTodo('New task')}>Add</button>
<For each={todos()}>{(todo) => <li>{todo.text}</li>}</For>
</div>
);
}
4.2 refetch 方法 #
jsx
function RefreshableData() {
const [data, { refetch }] = createResource(fetchData);
return (
<div>
<button onClick={() => refetch()}>Refresh</button>
<Show when={data()}>
{(d) => <pre>{JSON.stringify(d(), null, 2)}</pre>}
</Show>
</div>
);
}
五、总结 #
5.1 Resource API #
| API | 说明 |
|---|---|
createResource(source, fetcher) |
创建资源 |
resource() |
获取数据 |
resource.loading |
加载状态 |
resource.error |
错误信息 |
resource.mutate |
手动更新 |
resource.refetch |
重新获取 |
5.2 最佳实践 #
- 使用 Suspense 简化加载状态
- 处理错误情况
- 封装数据获取逻辑
- 使用 mutate 进行乐观更新
最后更新:2026-03-28