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

React中Context Provider内axios+react-query请求失效问题求助

问题分析与修复方案

你的核心问题出在React Hook规则违反和Context数据传递逻辑错误上,以下是具体问题和修复步骤:

问题1:Hook使用违反规则

你在普通函数RQKitsDB里调用了useQuery,但React Hook只能在组件顶层或以use开头的自定义Hook里调用,否则React不会执行这个Hook,自然不会发起axios请求,服务器也就收不到请求。

问题2:Context传递与使用错误

你把RQKitsDB函数放到了Context的value里,但在组件中直接尝试读取RQKitsDB.data——这相当于读取一个函数的data属性,必然得到undefined,根本没有调用这个函数去执行useQuery。


修复步骤

1. 重构kitDataContext.js

把useQuery移到Provider组件内部(组件属于Hook合法调用场景),并直接将请求结果放到Context中,同时用自定义Hook封装Context的获取逻辑:

import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
import { createContext, useContext } from 'react';

const kitsDataContext = createContext();

// 自定义Hook,封装Context获取,确保只能在Provider内部使用
export const useKitsData = () => {
  const context = useContext(kitsDataContext);
  if (!context) {
    throw new Error('useKitsData必须在KitsDataProvider内部使用');
  }
  return context;
};

export const KitsDataProvider = ({children}) => {
    // 修正fetchKits:直接返回axios请求,或用await取出数据(推荐后者,让react-query缓存实际数据)
    const fetchKits = async () => {
        const response = await axios.get("http://localhost:5001/kitsDB");
        return response.data; // 返回服务器返回的实际数据
    };

    // 在Provider组件顶层调用useQuery,符合Hook规则
    const { isLoading, data } = useQuery("kitsDB", fetchKits);

    // 将加载状态和数据直接传入Context
    return( 
        <kitsDataContext.Provider value={{ isLoading, data }}>
            {children}
        </kitsDataContext.Provider>
    );
};

2. 修改SerumRow.js使用数据

用自定义HookuseKitsData获取Context中的数据,并处理加载状态:

import "./row.css"
import {Button} from 'react-bootstrap';
import AddToCart from './AddToCart.js';

import { useKitsData } from './contexts/kitsDataContext.js'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { KitsDataProvider } from './contexts/kitsDataContext.js'

const queryClient = new QueryClient()

function SerumRowNoProviders() {
  // 使用自定义Hook获取数据和加载状态
  const { isLoading, data } = useKitsData();

  // 处理加载中状态
  if (isLoading) {
    return <div>加载中...</div>;
  }

  return (
      <div className="small-container">
        <h1>SERUM PRESETS</h1>
        <div className="row">
          {/* 使用data渲染实际数据,注意可选链避免空值报错 */}
          {data?.aa?.map((kit, index) => (
            <div key={index} className="col-3 text-center">
              <img src={kit.image || "./images/WavSupply-Sidepce-Elysium-Loop-Kit-920x920.jpg"} alt={`套件 ${index+1}`} />
              <div>{kit.name}</div>
              <div className="priceReact">{kit.price}</div>
              <AddToCart />
            </div>
          ))}
        </div>
        <h1><button type="button" id="show-more" className="btn btn-outline-dark btn-lg">浏览全部</button></h1>
      </div>
  );
}

function SerumRow() {
  return (
    <QueryClientProvider client={queryClient}>
      <KitsDataProvider>
        <SerumRowNoProviders />
      </KitsDataProvider>
    </QueryClientProvider>
  );
}

export default SerumRow;

额外注意点

  1. CORS配置:如果前后端端口不同(前端3000,后端5001),需要在后端配置CORS允许前端域名访问,否则会出现跨域错误。
  2. 数据结构适配:服务器返回的是{"aa": result},所以渲染时要通过data.aa访问数组数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:52:35