0Pricing
Frontend Academy · 课时

组件挂载时获取数据

在 useEffect 中从 API 获取 JSON,将响应保存到状态中,并使用空依赖数组仅触发一次获取操作。

组件挂载时获取数据 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。

数据获取模式

React 中标准的数据获取模式是:1)定义加载、错误和数据状态;2)在 useEffect 中使用空依赖数组 [] 获取数据;3)在回调中更新状态;4)根据状态进行渲染。

完整示例

这是一个完整示例:组件挂载时获取用户,并处理加载和错误状态。

interface User { id: number; name: string; email: string; }

function UserList() {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/users')
      .then(res => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.json();
      })
      .then(data => setUsers(data))
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <Spinner />;
  if (error)   return <ErrorMessage message={error} />;
  return <ul>{users.map(u => <UserItem key={u.id} {...u} />)}</ul>;
}

在 useEffect 中使用 async/await

useEffect 的回调不能直接使用 async(因为它会返回 Promise,而 React 会将其解释为清理函数)。相反,请定义一个内部的 async 函数并立即调用它。

useEffect(() => {
  async function fetchUsers() {
    try {
      const res = await fetch('/api/users');
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      setUsers(data);
    } catch (err) {
      setError((err as Error).message);
    } finally {
      setLoading(false);
    }
  }

  fetchUsers();
}, []);

检查响应状态

fetch 不会因 HTTP 错误(4xx、5xx)而抛出异常——它只会在网络失败时抛出异常。请始终检查 response.ok,并针对错误响应手动抛出异常。

const res = await fetch('/api/data');
if (!res.ok) {
  // Could also use res.status for specific handling
  throw new Error(`Server responded ${res.status}: ${res.statusText}`);
}
const data = await res.json();

依赖项变化时获取数据

将依赖项(例如路由参数或属性中的 ID)添加到副作用的依赖数组中。每当依赖项发生变化时,副作用都会重新运行并获取最新数据。

const { userId } = useParams();

useEffect(() => {
  if (!userId) return;
  setLoading(true);
  fetch(`/api/users/${userId}`)
    .then(r => r.json())
    .then(setUser)
    .finally(() => setLoading(false));
}, [userId]);

副作用中的 POST 请求

副作用也可以发送 POST、PUT、DELETE 请求,但这些请求通常由事件触发(表单提交、按钮点击),而不是由挂载时的副作用触发。请让副作用负责加载数据,并使用事件处理程序执行变更。

自定义 useFetch 钩子

将获取数据、加载和错误处理模式提取到自定义钩子中,以便在多个组件之间复用。

function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(r => { if (!r.ok) throw new Error(`${r.status}`); return r.json(); })
      .then(setData)
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

安全解析 JSON

请始终将 res.json() 包裹在 try/catch 中——格式错误的 JSON 会抛出 SyntaxError。外层 catch 会处理它,但了解错误来源有助于调试。

API 基础 URL 配置

不要将 API URL 硬编码。请使用环境变量(import.meta.env.VITE_API_URL)配置基础 URL。创建一个集中管理的 api.ts 文件,并在其中配置 fetch 包装器。

const API_BASE = import.meta.env.VITE_API_URL;

async function apiFetch<T>(path: string): Promise<T> {
  const res = await fetch(`${API_BASE}${path}`, {
    headers: { 'Authorization': `Bearer ${getToken()}` }
  });
  if (!res.ok) throw new Error(`API error ${res.status}`);
  return res.json();
}

何时迁移到 React Query

手动获取数据的模式适用于简单场景。当您需要缓存、后台重新获取、分页或数据变更时,请迁移到 React Query(TanStack Query)——它可以可靠地处理所有这些模式。

显示加载骨架屏

不要使用旋转指示器,而应显示与已加载内容形状相匹配的骨架界面。这样可以缩短用户感知的加载时间,并防止布局偏移。

快速检查

为什么不能直接将 useEffect 的回调设为 async?

回顾:在 useEffect 中获取数据

定义加载、错误和数据状态。在 useEffect 中使用空依赖数组 [] 获取数据。定义内部 async 函数,不要将回调设为 async。始终检查 res.ok。动态获取数据时,将 URL 或 ID 添加到依赖项中。将逻辑提取到 useFetch 自定义钩子中以便复用。在生产环境中获取数据时,请考虑使用 TanStack Query。

常见问题解答

「组件挂载时获取数据」课时是免费的吗?

是的 — 「组件挂载时获取数据」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。

「组件挂载时获取数据」这节课中我会学到什么?

在 useEffect 中从 API 获取 JSON,将响应保存到状态中,并使用空依赖数组仅触发一次获取操作。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Frontend Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「组件挂载时获取数据」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Frontend Academy 课中编写并运行代码吗?

能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. useEffect 基础:依赖与清理
  2. 组件挂载时获取数据
  3. 处理加载状态与错误状态
  4. 使用 AbortController 进行清理
← 返回 Frontend Academy