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

如何在API Context中注入Service并实现二者通信?

让Service与Context实现通信的方案

核心思路是让Context Provider调用Service的API请求方法,将请求结果更新到Context的状态中,同时把状态和触发请求的方法暴露给子组件使用。具体步骤如下:

1. 简化Service的写法(可选但更实用)

你的当前Service是一个工厂函数,其实可以直接导出请求函数,减少不必要的函数调用:

// CategoryService.js
export const fetchCategoryData = async () => {
    try {
        const response = await fetch("http://192.168.1.68:19000/animal/categories/main_groups/", {
            method: "GET",
        });
        if (!response.ok) {
            throw new Error("Network response was not ok");
        }

        return await response.json();
        
    } catch (error) {
        console.error("There was a problem with the fetch operation:", error);
        throw error;
    }
};

2. 在Context Provider中整合Service逻辑

修改Context Provider,导入Service的请求函数,封装加载数据的方法,同时管理加载状态、数据和错误信息:

// CategoryContext.js
import { createContext, useState, useCallback } from "react";
import { fetchCategoryData } from './CategoryService';

const CategoryContext = createContext();

export const CategoryContextProvider = (props) => {
    const [categoryList, setCategoryList] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null); // 新增错误状态,方便组件处理异常

    // 用useCallback缓存方法,避免组件重复渲染
    const loadCategoryData = useCallback(async () => {
        setLoading(true);
        setError(null);
        try {
            // 调用Service的请求函数获取数据
            const data = await fetchCategoryData();
            setCategoryList(data);
        } catch (err) {
            setError(err.message);
        } finally {
            // 请求结束无论成功失败都关闭加载状态
            setLoading(false);
        }
    }, []);

    // 可选:如果需要组件挂载时自动加载数据,取消下面的注释
    // useEffect(() => {
    //     loadCategoryData();
    // }, [loadCategoryData]);

    // 把状态和方法放入Context的value中
    const value = {
        categoryList,
        loading,
        error,
        loadCategoryData, // 提供给子组件触发数据加载的方法
    };

    return <CategoryContext.Provider value={value}>{props.children}</CategoryContext.Provider>;
};

export default CategoryContext;

3. 组件中使用Context消费数据和方法

在需要使用分类数据的组件中,通过useContext获取Context中的状态和方法:

// CategoryList.js
import { useContext, useEffect } from 'react';
import CategoryContext from './CategoryContext';

const CategoryList = () => {
    const { categoryList, loading, error, loadCategoryData } = useContext(CategoryContext);

    // 组件挂载时触发数据加载,也可以通过按钮点击等事件触发
    useEffect(() => {
        loadCategoryData();
    }, [loadCategoryData]);

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

    return (
        <ul>
            {categoryList.map(category => (
                <li key={category.id}>{category.name}</li>
            ))}
        </ul>
    );
};

export default CategoryList;

逻辑说明

  • Service只负责处理网络请求的底层逻辑,不关心状态管理
  • Context Provider负责管理数据状态、加载状态和错误状态,并封装调用Service的方法
  • 子组件只需通过Context获取状态和触发方法,无需直接和Service交互,实现了逻辑解耦

内容的提问来源于stack exchange,提问作者mightycode Newton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:55:34