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

React中如何从Sidebar组件向App.js导出数组?useContext报错求助

问题分析与解决方案

核心问题1:Context Provider层级错误

你的Sidebar是App的子组件,但AppContext.Provider被放在Sidebar内部,导致App组件不在Provider的覆盖范围内,调用useContext(AppContext)自然拿不到值,返回undefined。

核心问题2:components数组存储的是字符串而非组件

你在Sidebar里把app.jsx(字符串)存入components数组,就算拿到这个数组,也无法直接渲染字符串,必须存储实际导入的组件引用。


完整修复步骤

步骤1:调整Context Provider层级到App组件

将AppContext.Provider移到App组件外层,让App和Sidebar都处于Provider覆盖范围内:

修改App.js:

import { useContext } from 'react';
import { AppContext } from './appContext';
import Sidebar from './Sidebar';
// 导入所有需要渲染的组件
import ToDo from './ToDo';
import Card from './Card';
import Tracker from './Tracker';
import Metronome from './Metronome';

function App() {
  // 直接在App中定义应用配置,存储组件引用而非字符串
  const apps = [
    { name: 'To Do App', icon: FaTasks, component: ToDo },
    { name: 'Weather', icon: TiWeatherPartlySunny, component: Card },
    { name: 'Finance Tracker', icon: FaMoneyBill, component: Tracker },
    { name: 'Metronome', icon: BsFileEarmarkMusicFill, component: Metronome },
  ];
  const components = apps.map(app => app.component);

  return (
    <AppContext.Provider value={{ components, apps }}>
      <h1 className='text-black text-8xl text-center p-8 fancy-font '>All in One App</h1>
      <div className='App flex flex-row gap-[20px] flex-wrap relative'>
        {components.map((Comp, index) => (
          <Comp key={index} />
        ))}         
        <Sidebar/>
      </div>
    </AppContext.Provider>
  );
}

export default App;

步骤2:修改Sidebar组件,从Context获取apps配置

Sidebar不再需要自己定义apps,直接通过Context获取:

修改Sidebar.jsx:

import { useState, useContext } from 'react';
import { AppContext } from './appContext';
// 补全所有图标组件的导入路径
import FaTasks from '@fortawesome/react-fontawesome/...';
import TiWeatherPartlySunny from 'react-icons/ti/...';
import FaMoneyBill from '@fortawesome/react-fontawesome/...';
import BsFileEarmarkMusicFill from 'react-icons/bs/...';
import RxAllSides from 'react-icons/rx/...';

const Sidebar = () => {
  const { apps } = useContext(AppContext);
  const [isOpen, setIsOpen] = useState(false);

  const handleRender = (e) => {
    // 保留你的点击逻辑
  };

  return (
    <>
      {/* 侧边栏触发按钮,控制显示/隐藏 */}
      <button onClick={() => setIsOpen(!isOpen)}>Toggle Sidebar</button>
      
      {isOpen && (
        <div className='h-screen w-[310px] bg-white bg-opacity-90 top-0 right-0 fixed'>
          <div className='flex flex-row gap-3 my-7'>
            <RxAllSides className='text-4xl font-bold' />
            <h1 className='text-3xl'>All in One App</h1>
          </div>

          <div className='w-full flex-col justify-start align-start'>
            <h2 className='opacity-75 text-2xl py-5 ml-4'>APPS</h2>
            <div className='flex flex-col gap-7 mt-3'>
              {apps.map((app) => (
                <div
                  key={app.name}
                  className='flex w-full h-8 flex-row justify-between align-middle opacity-60 cursor-pointer relative hover:opacity-90 hover:scale-105 hover:transition-transform'
                  onClick={(e) => handleRender(e)}
                >
                  <app.icon className='text-3xl absolute top-[-4px] mr-2 left-9' />
                  <h2 className='text-2xl absolute left-[6.3rem]'>{app.name}</h2>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}
    </>
  );
};

export default Sidebar;

步骤3:给AppContext设置默认值(可选但推荐)

修改appContext.js,避免未定义的警告:

import { createContext } from 'react';

const AppContext = createContext({
  components: [],
  apps: []
});

export { AppContext };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:13:29