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

使用React Hooks+useHistory跳转页面后获取Context为undefined如何解决

问题根因

  1. Context作用域不匹配:你定义的classSelectedContext.Provider仅包裹了ClassSelection组件内部引入的ClassDetails实例,而路由配置中/class-detail路径对应的ClassDetails是独立渲染的,不在Provider的作用域范围内,自然无法拿到Context传递的值。
  2. 状态更新异步问题:setSelectedClass是异步更新的,你调用该方法后立即执行跳转,此时selectedClass还未更新为最新的选中值,即使作用域正确也可能拿到旧值。
  3. useEffect依赖错误:ClassSelection中拉取课程列表的useEffect依赖了selectedClass,会导致每次切换选中课程都重复拉取课程列表,属于不必要的请求。ClassDetails中的useEffect使用了空依赖数组,依赖的Context/路由参数更新时不会重新触发请求。

推荐解决方案(路由传参,实现最简单符合场景需求)

步骤1:修改路由配置,新增动态参数

// 路由文件中修改class-detail的路由规则
<PrivateRoute path="/class-detail/:classId" exact>
  <ClassDetails />
</PrivateRoute>

步骤2:修改ClassSelection的跳转逻辑

删除无用的selectedClass状态、Context定义、组件内部引入的ClassDetails和Provider包裹代码,直接将课程ID携带在路由中跳转:

// 修改跳转方法,接收课程ID参数
const onSelectedClassClicked = (classId) =>{
  history.push(`/class-detail/${classId}`)
}

// 修改按钮点击事件
<button 
  value={item.classIdentifier}
  onClick={(e) => {
    onSelectedClassClicked(e.target.value)
  }}>
  {item.className}
</button>

// 调整拉取课程列表的useEffect依赖为空数组,仅初始化时拉取一次
useEffect( () =>{
  // 原有axios请求逻辑不变
},[]);

步骤3:修改ClassDetails,从路由取参数

import { useHistory, useParams } from 'react-router-dom'; // 新增引入useParams

export const ClassDetails = () => {
  const [token, setToken] = useToken();
  const history = useHistory();
  const { classId } = useParams(); // 从路由参数获取选中的课程ID
  const authStr = 'Bearer '.concat(token); 

  useEffect( () =>{
    if(!classId) return; // 无参数时跳过请求
    console.log(classId)
    axios.get(`http://localhost:8081/user/class/${classId}`,  {
      headers: {
        'Authorization': authStr
      }
    })
    .then (res => {  
      console.log(res.data);
    })
    .catch(
      err =>{
        console.log(err);
        console.log("An error happenned")
      }
    );
  }, [classId, authStr]); // 依赖加上classId,参数变化时重新请求
  // 其余渲染逻辑不变
}

若坚持使用Context实现的解决方案

  1. 将classSelectedContext.Provider提升到路由组件的外层,包裹所有路由组件,同时将selectedClass状态和更新方法也提升到该层级,确保所有路由下的组件都能访问到Context。
  2. 调整跳转逻辑:由于setSelectedClass是异步的,不要在调用后立即跳转,可以新增useEffect监听selectedClass变化,当值不为空时再执行跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:24:02