children 是一个特殊的 prop,用于接收组件标签之间的内容,实现灵活的组件组合。

示例 1: 基本 children

文本 children

这是一段普通文本内容

混合 children

标题

描述文字

function Card({ children, title }) {
  return (
    <div className="card">
      {title && <h4>{title}</h4>}
      <div>{children}</div>  {/* 渲染 children */}
    </div>
  );
}

// 使用
<Card title="标题">
  <p>这是 children 内容</p>
</Card>

示例 2: 布局组件

Header

主内容区域

这里是 children,会渲染在 main 区域中。 sidebar 是另一个 prop,用于渲染侧边栏。

Footer
插槽模式: 使用多个 props(如 children + sidebar)可以实现多个内容插槽。

示例 3: 具名插槽

⚠️确认删除

确定要删除这条记录吗?此操作不可恢复。

<Dialog
  title={<span>⚠️ 确认删除</span>}
  footer={
    <>
      <Button>取消</Button>
      <Button variant="danger">删除</Button>
    </>
  }
>
  <p>确定要删除吗?</p>
</Dialog>

示例 4: Children API

Children.count: 3

#1第一个子元素
#2第二个子元素
#3第三个子元素

toArray 结果:

[3 个元素]

import { Children } from 'react';

function Component({ children }) {
  // 计数
  const count = Children.count(children);

  // 转为数组
  const array = Children.toArray(children);

  // 遍历
  return Children.map(children, (child, index) => (
    <div key={index}>{child}</div>
  ));
}

示例 5: cloneElement

Toolbar 组件自动为所有子元素添加统一样式:

import { Children, cloneElement, isValidElement } from 'react';

function Toolbar({ children }) {
  return (
    <div className="toolbar">
      {Children.map(children, (child) => {
        if (isValidElement(child)) {
          // 克隆并添加额外的 className
          return cloneElement(child, {
            className: `${child.props.className} toolbar-item`,
          });
        }
        return child;
      })}
    </div>
  );
}
注意: cloneElement 会使 props 来源变得不透明, 建议优先考虑使用 Context 或组合模式。

示例 6: 函数作为 Children

移动鼠标查看坐标:

(0, 0)

鼠标位置

interface MouseTrackerProps {
  children: (position: { x: number; y: number }) => React.ReactNode;
}

function MouseTracker({ children }: MouseTrackerProps) {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  return (
    <div onMouseMove={handleMouseMove}>
      {children(position)}  {/* 调用函数,传入数据 */}
    </div>
  );
}

// 使用
<MouseTracker>
  {({ x, y }) => <p>位置: ({x}, {y})</p>}
</MouseTracker>
Render Props 模式: 将函数作为 children, 让父组件可以将数据传递给子组件的渲染逻辑。

示例 7: children 的各种类型

字符串

子元素数量:1
Hello World

数字

子元素数量:1
42

JSX 元素

子元素数量:1
React Element

数组

子元素数量:3
ABC

null(不渲染)

子元素数量:0
(空)

混合内容

子元素数量:3
文本加粗123