FumadocsZDecode
React

React.Children.map

React.Children.map 用来安全遍历 children,并给每个子节点做包装处理。之所以需要它,是因为 React 的 children 不一定是数组——直接调 .map() 会报错。

Children.map 内部会自动规范化 children:单个节点、数组、字符串、null 都能正确处理。


一、为什么不能直接用 children.map

children 可能是以下任何一种情况,只有数组才有 .map() 方法:

children 值typeof能直接 .map()
<div />(单个)object
[<A/>, <B/>]array
'hello'(字符串)string
nullobject(null)
undefinedundefined

所以 React 提供了 React.Children.map,等价于先在内部做了一层规范化:

// 粗暴等价理解(React 内部实现更复杂,会额外处理 key、Fragment、null)
const safeChildren = Array.isArray(children) ? children : [children]
safeChildren.map((child) => {
  /* ... */
})

二、核心示例

下面是一个典型的 RowList 组件,给每个 children 外面包一层 <div class="row">

import { Children } from 'react'

function RowList({ children }) {
  return (
    <div>
      {Children.map(children, (child) => (
        <div className="row">{child}</div>
      ))}
    </div>
  )
}

使用时:

function Demo() {
  return (
    <RowList>
      <span>A</span>
      <span>B</span>
    </RowList>
  )
}

渲染结果为每个 <span> 外层包一层 <div class="row">

<div>
  <div class="row"><span>A</span></div>
  <div class="row"><span>B</span></div>
</div>

三、常用 API

React.Children 提供 5 个静态方法:

API作用
Children.map遍历 children,对每个子节点做转换并返回新数组
Children.forEach仅遍历,不返回新数组
Children.count统计 children 数量(null/undefined 计为 0)
Children.only验证只有一个子元素,否则抛错;常用于单子组件
Children.toArray将 children 转换为真正的数组,并自动处理 key 去重

四、使用场景

现在写业务代码时,大多数情况下直接渲染 {children} 就够了。Children.map 主要用在组件库和插槽封装中,比如 Tabs、Form、Menu、Table、Layout 等需要统一给 children 添加属性或包装 DOM 的场景。


五、面试总结

面试时可以这样回答:

React.Children.map 用于安全遍历 children。因为 children 可能是单个元素、字符串或 null,不存在 .map() 方法。Children.map 内部做了规范化处理,即便是单个 child 也能正常遍历。典型用法是给每个 children 外层包一层容器——本质是一个安全的 children 包装函数。

On this page