You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API数据初始化React Context?

正确实现异步数据源初始化React Context的方法

你直接在模块顶层使用await fetch不可行的原因有两个:一是模块顶层await需要特定环境配置(比如ES模块),二是就算能执行,Provider组件内部的useState初始值会覆盖Context的默认值,等于白做。下面是正确的实现方式:

核心思路

  • Context的默认值仅作为兜底方案(给未被Provider包裹的组件使用),实际数据由Provider通过state管理
  • 在Provider组件内部,使用useEffect钩子在组件挂载后执行异步请求,获取数据后更新state
  • 可选:添加加载/错误状态,提升用户体验

修改后的完整代码

import React, { createContext, useState, useEffect } from "react";
import { Usuario } from "../typings/types";

interface UsuariosContextType {
  usuarios: Usuario[];
  isLoading: boolean;
  error: string | null;
  setUsuario?: React.Dispatch<React.SetStateAction<Usuario[]>>;
}

// 设置兜底的默认值,仅在未被Provider包裹时生效
export const UsuariosContext = createContext<UsuariosContextType>({
  usuarios: [],
  isLoading: true,
  error: null,
});

// 修正Provider的props解构,children是props的属性
export const UsuariosProvider = ({ children }: { children: React.ReactNode }) => {
  const [usuarios, setUsuario] = useState<Usuario[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchUsuarios = async () => {
      try {
        setIsLoading(true);
        const response = await fetch(`http://localhost:8080/usuarios`, { cache: 'no-store' });
        if (!response.ok) throw new Error('请求失败');
        const usuariosArray: Usuario[] = await response.json();
        setUsuario(usuariosArray);
        setError(null);
      } catch (err) {
        setError(err instanceof Error ? err.message : '未知错误');
        setUsuario([]);
      } finally {
        setIsLoading(false);
      }
    };

    fetchUsuarios();
  }, []); // 空依赖数组确保只在组件挂载时执行一次

  return (
    <UsuariosContext.Provider value={{ usuarios, isLoading, error, setUsuario }}>
      {children}
    </UsuariosContext.Provider>
  );
};

关键修改点说明

  1. 修正Context默认值:添加了isLoading和error状态,让兜底场景也能有合理的状态反馈
  2. Provider参数修正:正确解构children props,符合React组件的参数规范
  3. 异步请求移至useEffect:在组件挂载后执行fetch,避免顶层await的问题,同时能通过state更新数据
  4. 添加状态管理:增加加载和错误状态,方便消费组件处理不同场景(比如显示加载动画、错误提示)
  5. 错误处理:捕获请求失败的情况,避免程序崩溃并给出错误信息

使用示例

在消费组件中,你可以这样使用Context:

import { useContext } from "react";
import { UsuariosContext } from "./UsuariosContext";

const UsuarioList = () => {
  const { usuarios, isLoading, error } = useContext(UsuariosContext);

  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;

  return (
    <ul>
      {usuarios.map(usuario => (
        <li key={usuario.id}>{usuario.nome}</li>
      ))}
    </ul>
  );
};

内容的提问来源于stack exchange,提问作者Thiago Barboza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:02:38