『React』子组件的导出与使用:小白也能懂的组件组织方式

点赞 + 关注 + 收藏 = 学会了

在 React 中,我们经常需要把一个大组件拆分成多个相关的小组件(比如导航栏组件包含多个导航项组件)。这种 “父组件 + 子组件” 的组合方式能让代码更清晰、更易维护。

本文就来教你:如何定义子组件、如何导出子组件,以及如何在父组件中使用它们。全程用最简单的语言和示例,小白也能轻松学会!

什么是 “父组件” 和 “子组件”?

简单说:

  • 父组件:可以理解为 “容器”,负责整体结构。
  • 子组件:是父组件内部的 “零件”,负责具体功能。

比如一个导航栏(Menu)是父组件,里面的每个导航项(Item)就是子组件。它们是 “整体与部分” 的关系,通常一起出现、一起使用。

子组件的导出与使用:3 步走

我以 “导航菜单” 为例,一步步实现父组件包含子组件的完整流程。

第一步:创建组件文件,定义父组件和子组件

首先在项目中新建一个组件文件夹(通常叫components),再创建一个Menu文件夹,里面放index.js文件(约定俗成的命名方式)。

// components/Menu/index.js
import React from 'react';

// 1. 定义父组件:导航栏容器
function Menu({ children }) {
  // children 是一个特殊属性,用来接收组件标签内的内容
  return (
    <nav style={{ 
      backgroundColor: '#333', 
      padding: '10px', 
      display: 'flex', 
      gap: '15px' 
    }}>
      {/* 这里会显示子组件的内容 */}
      {children}
    </nav>
  );
}

// 2. 定义子组件:导航项
function Item({ children }) {
  return (
    <a 
      href="#" 
      style={{ 
        color: 'white', 
        textDecoration: 'none', 
        padding: '5px 10px' 
      }}
    >
      {children} {/* 接收导航项的文字内容 */}
    </a>
  );
}

// 3. 关键步骤:把Item作为Menu的属性,关联起来
Menu.Item = Item;

// 4. 导出父组件(子组件会跟着父组件一起被导出)
export default Menu;

重点说明

  • Menu.Item = Item 这行代码是 “绑定” 子组件到父组件的关键,让子组件成为父组件的一个属性。
  • 这样做的好处是:使用时能清晰看出 “Item 是 Menu 的一部分”,避免命名混乱。

第二步:在页面中导入父组件

接下来在主页面(比如App.js)中导入刚才定义的Menu组件(子组件会跟着一起被导入)。

// App.js
import React from 'react';
// 只需要导入父组件即可,子组件会作为其属性存在
import Menu from './components/Menu';

第三步:使用父组件和子组件

导入后,就可以像这样使用子组件:父组件.子组件(比如Menu.Item)。

// App.js 完整代码
import React from 'react';
import Menu from './components/Menu';

function App() {
  return (
    <div style={{ padding: '20px' }}>
      <h1>我的网站</h1>

      {/* 使用父组件Menu */}
      <Menu>
        {/* 用Menu.Item使用子组件,内容写在标签中间 */}
        <Menu.Item>首页</Menu.Item>
        <Menu.Item>产品</Menu.Item>
        <Menu.Item>关于我们</Menu.Item>
        <Menu.Item>联系客服</Menu.Item>
      </Menu>
    </div>
  );
}

export default App;

页面会显示一个黑色导航栏,里面有 4 个白色的导航链接,这就是父组件Menu包含 4 个子组件Menu.Item的效果。就是前面截图的样子了。

为什么要这样组织组件?

可能你会问:直接单独导出子组件不行吗?比如:

// 另一种方式:单独导出子组件
export function Menu() { ... }
export function Item() { ... }

// 使用时单独导入
import { Menu, Item } from './components/Menu';

这种方式当然可以,但用父组件.子组件的方式有 3 个明显好处:

  1. 关系更清晰:看到Menu.Item就知道这是 Menu 的子组件,不是其他组件。
  2. 避免命名冲突:如果有多个组件都有Item子组件(比如Menu.ItemList.Item),不会混淆。
  3. 符合直觉:就像 “电脑。键盘”“手机。屏幕” 一样,子组件是父组件的一部分,使用起来更自然。

再举一个例子:用户信息组件

为了加深理解,我们再做一个 “用户信息” 组件:父组件UserCard(用户卡片)包含子组件UserCard.Avatar(头像)和UserCard.Info(信息)。

// components/UserCard/index.js
import React from 'react';

// 父组件:用户卡片容器
function UserCard({ children }) {
  return (
    <div style={{ 
      border: '1px solid #ddd', 
      borderRadius: '8px', 
      padding: '15px', 
      maxWidth: '300px' 
    }}>
      {children}
    </div>
  );
}

// 子组件1:头像
function Avatar({ src, alt }) {
  return (
    <img 
      src={src} 
      alt={alt}
      style={{ 
        width: '80px', 
        height: '80px', 
        borderRadius: '50%' 
      }}
    />
  );
}

// 子组件2:用户信息
function Info({ name, role }) {
  return (
    <div style={{ marginTop: '10px' }}>
      <h3 style={{ margin: 0 }}>{name}</h3>
      <p style={{ color: '#666', margin: '5px 0 0 0' }}>{role}</p>
    </div>
  );
}

// 绑定子组件到父组件
UserCard.Avatar = Avatar;
UserCard.Info = Info;

// 导出父组件
export default UserCard;

使用时:

// App.js 中使用
import UserCard from './components/UserCard';

function App() {
  return (
    <div style={{ padding: '20px' }}>
      <UserCard>
        <UserCard.Avatar 
          src="https://picsum.photos/id/64/200/200" 
          alt="用户头像" 
        />
        <UserCard.Info 
          name="张三" 
          role="前端开发工程师" 
        />
      </UserCard>
    </div>
  );
}

这样就实现了一个包含头像和信息的用户卡片,结构清晰,使用方便。

总结

  1. 子组件定义:在父组件同一个文件中定义相关的子组件。
  2. 绑定子组件:通过父组件.子组件 = 子组件的方式关联(如Menu.Item = Item)。
  3. 导出与导入:只需要导出父组件,导入后通过父组件.子组件使用。
  4. 核心优势:关系清晰、避免冲突、使用直观。

这种组件组织方式在实际开发中非常常用,很多 UI 库(如 Ant Design、Material-UI)都在用。掌握它,你的 React 代码会更专业、更好维护!

现在就动手试试吧:把上面的示例代码复制到你的项目中,运行看看效果,再尝试修改样式或添加新的子组件,加深理解~


以上就是本文的全部内容啦,想了解更多React用法的工友可以关注《React 中文教程》

也可以➕我 green bubble 吹吹水咯

点赞 + 关注 + 收藏 = 学会了

本作品采用《CC 协议》,转载必须注明作者和本文链接
公众号:德育处主任
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!