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

Next.js中如何将组件作为Props传递并使用?

解决组件作为Props传递后的使用问题

问题根源梳理

你的代码存在几个关键错误,导致传递的组件无法正常工作:

  • Props名称不匹配:父组件传递的是video/condensed/full(小写开头),但子组件试图解构Video/Condensed/Full(大写开头),名称完全对应不上。
  • 传递的是渲染好的元素而非组件:父组件传的是<Video/>(已渲染的React元素),但子组件里又尝试重新渲染<Video/>,这是重复操作,应该直接使用传递过来的元素。
  • 状态更新方式错误:setActiveComponent是函数,必须通过调用setActiveComponent(值)来更新状态,而不是赋值setActiveComponent=<Video/>。
  • Switch语句缺少break:每个case执行后没有break,会导致后续所有case都被执行。
  • Props参数结构错误:setActiveComponent是props的一部分,不能单独作为第二个参数,需要从props对象里解构。

修正后的代码

页面文件 career.tsx

import { useState } from 'react';
import ModuleToggle_withState from './ModuleToggle_withState'; // 确保导入路径正确

export function Full() {
   return ( <Text>Full</Text> );
}

export function Condensed() {
   return ( <Text>Condensed</Text> );
}

export function Video() {
   return ( <Text>Video</Text> );
}

export default function Career() {
   const [activeComponent, setActiveComponent] = useState<JSX.Element | null>(null);
   
   return (
      <>
         <Title>Career</Title>

         {/* 传递渲染好的元素作为props */}
         <ModuleToggle_withState 
            video={<Video/>} 
            condensed={<Condensed/>} 
            full={<Full/>}
            setActiveComponent={setActiveComponent} 
         />

         { activeComponent }
      </>
   );
}

组件文件 ModuleToggle_withState.tsx

import { useEffect, useState } from 'react';

// 定义Props类型,替代any
type ModuleToggleProps = {
  video: JSX.Element;
  condensed: JSX.Element;
  full: JSX.Element;
  setActiveComponent: (component: JSX.Element | null) => void;
};

export function ModuleToggle_withState({ video, condensed, full, setActiveComponent }: ModuleToggleProps) {
   // 假设section是组件内部切换的状态
   const [section, setSection] = useState<string>('video');

   useEffect(() => {
      let targetComponent: JSX.Element | null = null;
      switch(section) {
         case 'video':
            targetComponent = video;
            break; // 添加break阻止后续case执行
         case 'condensed':
            targetComponent = condensed;
            break;
         case 'full':
            targetComponent = full;
            break;
         default:
            targetComponent = null;
      }
      setActiveComponent(targetComponent); // 调用状态更新函数
   }, [section, video, condensed, full, setActiveComponent]); // 添加完整依赖项

   return (
      <div>
         {/* 示例切换按钮,点击更新section状态 */}
         <button onClick={() => setSection('video')}>Video</button>
         <button onClick={() => setSection('condensed')}>Condensed</button>
         <button onClick={() => setSection('full')}>Full</button>
      </div>
   );
}

额外优化建议

  • 如果你想传递组件本身而非渲染好的元素(方便子组件给组件传递额外props),父组件可以直接传函数:video={Video},子组件里渲染时用<video {...yourProps}/>。
  • 始终避免使用any类型,定义明确的Props类型可以提前发现类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:25:20