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

使用useContext传递数据时返回undefined,无法正常显示问题求助

React useContext 数据传递异常问题解决

问题根源

你的UserContext.Provider和TypeContext.Provider定义在Cards组件内部,仅包裹了当前Card元素及内部的Link。但View组件是通过路由跳转渲染的独立页面,完全不在Provider的组件树范围内,因此useContext无法获取到Context值,只能返回默认的undefined。

解决方案

方案一:将Provider提升到路由上层(适用于全局共享数据)

如果这两个值是全局通用的,把Provider移到包裹路由的根组件(比如App.js)中:

  1. 抽离Context到单独文件(可选,更规范)
    创建src/contexts/AppContext.js:
import React from 'react';

export const UserContext = React.createContext();
export const TypeContext = React.createContext();
  1. 在App.js中用Provider包裹路由
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Cards from './Cards';
import View from './View';
import { UserContext, TypeContext } from './contexts/AppContext';

function App() {
  return (
    <UserContext.Provider value={'islam'}>
      <TypeContext.Provider value={'Abdelradi'}>
        <Router>
          <Routes>
            <Route path="/" element={<Cards />} />
            <Route path="/View/:id" element={<View />} />
          </Routes>
        </Router>
      </TypeContext.Provider>
    </UserContext.Provider>
  );
}

export default App;
  1. 移除Cards组件内部的Provider
    修改Cards.jsx,删除原本的Context Provider代码:
import React from 'react'
import Button from 'react-bootstrap/Button';
import Card from 'react-bootstrap/Card';
import { Link } from 'react-router-dom';

function Cards({item}) {
    return (
        <Card className='mr-3 rounded-tl-xl rounded-tr-xl my-2' key={item.id}>
            <div className='h-[330px]'>
                <Card.Img variant="top" className='rounded-tl-xl rounded-tr-xl h-[100%]' src={item.img} />
            </div>
            <Card.Body>
                <Card.Title>{ item.title }</Card.Title>
                <Card.Subtitle className="mb-2 text-muted text-[13px]">{ item.country}</Card.Subtitle>
                <hr />
                <div className='flex justify-between px-3'>
                    <p>CULTURAL <br /> RELAX</p>
                    <h1 className=' font-bold text-2xl text-slate-700'>${item.price}</h1>
                </div>
                <hr />
                <Card.Text className=' text-[14px] text-slate-500'>
                    {item.text }
                </Card.Text>
                <Link to={`/View/${item.id}`}>
                    <Button variant="primary " className='btns border-none rounded-full  text-[14px] px-10 text-white py-2 my-2  '>DETAILS</Button>
                </Link>
            </Card.Body>
        </Card>
    )
}

export default Cards
  1. View组件保持不变
    此时View组件就能正常通过useContext获取到全局Context的值。

方案二:通过路由state传递数据(适用于单个Card的特定数据)

如果你的目的是传递当前Card的专属数据,用React Router的state更合适,无需Context:

  1. 修改Cards组件的Link,添加state参数
<Link to={`/View/${item.id}`} state={{ user: 'islam', type: 'Abdelradi' }}>
    <Button variant="primary " className='btns border-none rounded-full  text-[14px] px-10 text-white py-2 my-2  '>DETAILS</Button>
</Link>
  1. 在View组件中通过useLocation获取state
import React from 'react'
import { useLocation, useNavigate } from 'react-router-dom';

function View() {
    const location = useLocation();
    const navigate = useNavigate();
    const { user, type } = location.state || {};
    console.log({user}, {type});

    return (
        <div className='mt-5'>
            <div className="container">
                <div className="row">
                    <div className="col text-white">
                        <div className='devimgview'>
                        </div>
                        <h1>{user},{type}</h1>
                        <button className='btn btn-secondary' onClick={() => navigate(-1)}>back</button>
                    </div>
                    <div className="col-md-6 align-items-center d-flex btn-leftview">
                    </div>
                </div>
            </div>
        </div>
    )
}

export default View

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:55:23