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

React中useContext报错:page未定义,子菜单无法正常显示

React useContext 子菜单报错:page is undefined 解决方案

问题场景

使用React的useContext Hook开发Navbar和Submenu组件时,Navbar功能正常,但鼠标悬停Navbar触发子菜单时,Submenu组件抛出错误:Uncaught TypeError: _Context__WEBPACK_IMPORTED_MODULE_1__.useGlobalContext().page is undefined

报错原因分析

  1. Context初始状态缺失:全局Context的初始state未给page设置默认结构,组件挂载时page为undefined,直接解构page: { page, links }触发报错。
  2. Navbar传参与数据不匹配:Navbar传递的page名称(如按钮文本"Product")与data.js中的page值(如"products")大小写不一致,导致无法匹配到对应数据,Context中的page仍为undefined。
  3. Submenu未做边界处理:Submenu组件在渲染和useEffect钩子中直接使用page和links,未处理它们为undefined的情况。

分步解决方案

1. 完善Context的初始状态与匹配逻辑

确保Context的state包含page的默认结构,并且在openSubmenu函数中正确匹配data.js的页面数据:

// Context.js
import { createContext, useContext, useState } from 'react';
import sublinks from './data';

const GlobalContext = createContext();

export const GlobalProvider = ({ children }) => {
  const [isSubmenuOpen, setIsSubmenuOpen] = useState(false);
  // 初始化page为带默认值的对象,避免解构报错
  const [page, setPage] = useState({ page: '', links: [] });
  const [location, setLocation] = useState({ center: 0, bottom: 0 });

  const openSubmenu = (pageName, coords) => {
    // 忽略大小写匹配data.js中的页面数据
    const matchedPage = sublinks.find(item => item.page.toLowerCase() === pageName.toLowerCase());
    // 找不到匹配项时设置默认空结构,避免后续报错
    setPage(matchedPage || { page: '', links: [] });
    setLocation(coords);
    setIsSubmenuOpen(true);
  };

  const closeSubmenu = () => {
    setIsSubmenuOpen(false);
  };

  return (
    <GlobalContext.Provider value={{ isSubmenuOpen, page, location, openSubmenu, closeSubmenu }}>
      {children}
    </GlobalContext.Provider>
  );
};

export const useGlobalContext = () => useContext(GlobalContext);

2. 修复Navbar的传参匹配问题

调整Navbar中displaySubmenu函数的page处理逻辑(结合Context的兼容处理,这里无需额外修改,若需要严格匹配,可将按钮文本改为与data.js一致的名称,比如"Products"):

// Navbar.js
const displaySubmenu = (e) => {
  const page = e.target.textContent;
  const tempBtn = e.target.getBoundingClientRect();
  const center = (tempBtn.left + tempBtn.right) / 2;
  const bottom = tempBtn.bottom - 3;
  openSubmenu(page, { center, bottom });
};

3. Submenu添加空值判断与边界处理

在Submenu组件中,对page和links设置解构默认值,同时在渲染和useEffect中添加空值校验:

// Submenu.js
import React, { useState, useRef, useEffect } from "react";
import {useGlobalContext} from '../../Context'

const Submenu = () => {
  const {
    isSubmenuOpen,
    page: { page = '', links = [] }, // 解构时设置默认值
    location,
  } = useGlobalContext();
  const container = useRef(null);
  const [columns, setColumns] = useState("col-2");
  
  useEffect(() => {
    if (!isSubmenuOpen || !location) return; // 子菜单关闭或无位置信息时不执行
    setColumns("col-2");
    const submenu = container.current;
    const { center, bottom } = location;
    submenu.style.left = `${center}px`;
    submenu.style.top = `${bottom}px`;
    
    if (links.length === 3) {
      setColumns("col-3");
    }
    if (links.length > 3) {
      setColumns("col-4");
    }
  }, [isSubmenuOpen, page, location, links]);
  
  return (
    <aside
      className={`${isSubmenuOpen ? "submenu show" : "submenu"}`}
      ref={container}
    >
      {/* 仅在子菜单打开且有有效page时渲染内容 */}
      {isSubmenuOpen && page && (
        <section>
          <h4>{page}</h4>
          <div className={`submenu-center ${columns}`}>
            {links.map((link, index) => {
              const { url, icon, label } = link;
              return (
                <a key={index} href={url}>
                  {icon}
                  {label}
                </a>
              );
            })}
          </div>
        </section>
      )}
    </aside>
  );
};

export default Submenu;

4. 确保App组件被GlobalProvider包裹

所有使用useGlobalContext的组件必须在GlobalProvider范围内,修改App.js:

// App.js
import Navbar from "./Component/Navbar/Navbar";
import Submenu from "./Component/Submenu/Submenu";
import { GlobalProvider } from './Context';

function App() {
  return (
    <GlobalProvider>
      <Navbar />
      <Submenu />
    </GlobalProvider>
  );
} 

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:24:29