资源与异步 #

一、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 最佳实践 #

  1. 使用 Suspense 简化加载状态
  2. 处理错误情况
  3. 封装数据获取逻辑
  4. 使用 mutate 进行乐观更新
最后更新:2026-03-28