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

React使用useContext传递Rapid API数据至HomePage失败,求助

修复useContext数据共享问题的方案

问题分析

你的代码存在几个关键问题导致数据无法传递:

  • 创建Context时传入了未定义的coinRanking,默认值无效
  • useQuery的请求函数写法错误,提前执行了axios请求,不符合useQuery的工作逻辑
  • 未导出作为Context Provider容器的QueryData组件,仅导出了Context本身
  • HomePage组件没有通过useContext消费Context中的数据

修复步骤及代码

1. 修正Context定义与组件导出

import React from 'react'
import { useQuery } from "react-query"
import axios from 'axios'
import { createContext, useContext } from 'react';
import HomePage from '../Pages/HomePage';

const options = {
  method: 'GET',
  url: 'https://coinranking1.p.rapidapi.com/coins',
  params: {
    referenceCurrencyUuid: 'yhjMzLPhuIDl',
    timePeriod: '24h',
    'tiers[0]': '1',
    orderBy: 'marketCap',
    orderDirection: 'desc',
    limit: '50',
    offset: '0'
  },
  headers: {
    'X-RapidAPI-Key': 'ea3e0e9305msh25681129077648ep1f06f9jsnb2ee8da018dc',
    'X-RapidAPI-Host': 'coinranking1.p.rapidapi.com'
  }
};

// 给Context设置合理的默认占位值
const DataContext = createContext({ 
  coinRanking: null,
  isLoading: false,
  isError: false,
  error: null
});

// 封装自定义Hook,简化子组件消费Context的逻辑
export const useDataContext = () => useContext(DataContext);

function QueryData({children}) {
  // 把axios请求放在useQuery的回调函数中,由useQuery控制请求时机与缓存
  const {data, isLoading, isError, error} = useQuery("coinData", () => axios.request(options))
  
  // 整理要传递给子组件的Context数据
  const contextValue = {
    coinRanking: data?.data?.data.stats,
    isLoading,
    isError,
    error
  }

  // 始终渲染Provider,将加载、错误状态也传递给子组件
  return (
    <DataContext.Provider value={contextValue}>
      {isLoading ? <p>Loading</p> : isError ? <p>{error.message}</p> : children}
    </DataContext.Provider>
  )
}

// 导出QueryData组件,用于包裹需要消费数据的子组件
export default QueryData

2. 在HomePage中消费Context数据

// HomePage.jsx
import { useDataContext } from '../path/to/QueryData'; // 替换为你的实际文件路径

function HomePage() {
  const { coinRanking } = useDataContext();

  if (!coinRanking) return null;

  return (
    <div>
      <h1>加密货币汇总数据</h1>
      <p>总市值: {coinRanking.totalMarketCap}</p>
      <p>加密货币总数: {coinRanking.totalCoins}</p>
      {/* 根据实际返回数据结构渲染其他内容 */}
    </div>
  )
}

export default HomePage;

3. 在应用入口使用QueryData包裹HomePage

比如在App.js中:

import QueryData from './path/to/QueryData';
import HomePage from './Pages/HomePage';

function App() {
  return (
    <QueryData>
      <HomePage />
    </QueryData>
  )
}

export default App;

关键说明

  • Context默认值是组件不在Provider范围内时的占位值,需设置符合业务逻辑的初始值
  • useQuery的回调必须返回Promise,不能提前执行axios请求,否则会导致重复请求、缓存失效
  • 自定义HookuseDataContext可以避免子组件重复编写useContext(DataContext),提升代码复用性
  • 将加载、错误状态放入Context,可让子组件根据状态灵活处理UI,也可保留你原有的逻辑,在Provider中直接渲染加载/错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:15:46