likes
comments
collection
share

React 顶层API之React.Children

作者站长头像
站长
· 阅读数 17

React.Children 提供了用于处理 this.props.children 不透明数据结构的实用方法。

React.Children 源码

在控制台中打印 React.Children,结果如下图:

React 顶层API之React.Children

可以看到,React.Children 提供了count、forEach、map、only、toArray 五个方法来处理this.props.children 。

下面,通过一个简单的例子来讲解一下这几个方法的使用。示例代码如下:

import React from "react";
import "./App.css";

function App() {
  console.log("React.Children:", React.Children);
  return (
    <div className="App">
      <ButtonList>
        <button type="submit" id="button1">
          1
        </button>
        <button id="button2">2</button>
      </ButtonList>
    </div>
  );
}

function ButtonList(props) {
  const { children } = props;
  console.log("props.children:", props.children);
  console.log(
    "React.Children.toArray(children):",
    React.Children.toArray(children)
  );
  console.log(
    "React.Children.map():",
    React.Children.map(children, function (thisArg) {
      console.log("thisArg", thisArg);
    })
  );
  console.log(
    "React.Children.forEach():",
    React.Children.forEach(children, function (thisArg) {
      console.log("forEach children:", children);
      console.log("forEach thisArg:", thisArg);
    })
  );

  console.log("React.Children.count():", React.Children.count(children));

  console.log("React.Children.only():", React.Children.only(children));

  return <div>{props.children}</div>;
}

export default App;
import React from "react";
import "./App.css";

function App() {
  console.log("React.Children:", React.Children);
  return (
    <div className="App">
      <ButtonList>
        <button type="submit" id="button1">
          1
        </button>
        <button id="button2">2</button>
      </ButtonList>
    </div>
  );
}

function ButtonList(props) {
  const { children } = props;
  console.log("props.children:", props.children);
  console.log(
    "React.Children.toArray(children):",
    React.Children.toArray(children)
  );
  console.log(
    "React.Children.map():",
    React.Children.map(children, function (thisArg) {
      console.log("thisArg", thisArg);
    })
  );
  console.log(
    "React.Children.forEach():",
    React.Children.forEach(children, function (thisArg) {
      console.log("forEach children:", children);
      console.log("forEach thisArg:", thisArg);
    })
  );

  console.log("React.Children.count():", React.Children.count(children));

  console.log("React.Children.only():", React.Children.only(children));

  return <div>{props.children}</div>;
}

export default App;

在上面的示例代码中,定义了一个 ButtonList 的组件,在该组件中直接使用 props.children 来渲染 ButtonList 组件的子组件。在 App 组件中使用 ButtonList 组件,并传入两个 button 子组件。

props.children

使用console.log("props.children:", props.children) 打印出 props.children,如下图所示:

React 顶层API之React.Children

React.Children.count(children)

React.Children.count 返回 children 中的组件总数量,等同于通过 map 或 forEach 调用回调函数的次数。在示例中,ButtonList 组件的子组件为两个,那么 props.children 有两个子节点,React.Children.count(children) 返回的值是 2 。

React.Children.forEach(children, function(thisArg){})

如果 children 是一个数组,那么它将会被遍历并为数组中的每个子节点调用回调函数。回调函数中的 thisArg 参数就是当前被遍历的子节点。如下图所示:

React 顶层API之React.Children

React.Children.map(children, function(thisArg){})

React.Children.map 用来遍历 children 里的每个子节点,每个子节点都会调用回调函数,回调函数中的thisArg 就是当前遍历的子节点,如下图:React 顶层API之React.Children

如果子节点不为 null 或 undefined ,那么该方法将会返回一个数组,返回后的数组中的每个子节点都会被分配一个 key,如下图所示:

React 顶层API之React.Children

React.Children.only(children)

React.Children.only 用来验证 children 是否仅有一个子节点 (一个 React 元素),如果是则返回这个子节点,否则会抛出错误。

  • children仅有一个子节点,则返回该子节点,如下图:

React 顶层API之React.Children

  • 如果有多个子节点,则抛出错误,如下图:

React 顶层API之React.Children

React.Children.toArray(children)

React.Children.toArray 会将 children 这个复杂的数据结构以数组的方式扁平展开并返回,并为每个子节点分配一个 key。在控制台中打印出经过 React.Children.toArray 处理后的 props.children,如下图所示:

React 顶层API之React.Children

toArray 为 props.children 的每个子节点的 key 添加了前缀。除此之外,如果 props.children 只有一个子节点,那么props.children是一个object对象,toArray会将 props.children 转化成一个数组。如下面的 props.children 截图和 React.Children.toArray(children) 截图。

props.children 是一个对象:

React 顶层API之React.Children

经过 React.Children.toArray(children) 处理后,props.children 被转化成一个数组:

React 顶层API之React.Children

何时使用

在封装组件时,可以通过props的方式传入子组件的数据,例如通过 dataSoure 属性传入数据,在组件内部通过 dataSoure 渲染子组件。也可以通过 JSX 的方式直接传入子组件,此时在组件内部通过 props.children 获取到子组件数据并渲染。如果需要对 props.children 中的数据做额外的处理,就可以使用 React.Children 提供的方法来处理。本文的示例就是通过 JSX 的方式直接传入子组件,如果需要获取子组件的的 id、type 等属性值,那么就可以使用 React.Children.toArray(children) 转化成数组后,获取每个子组件的 props 属性即可获取到子组件的的 id、type 等属性值。

转载自:https://juejin.cn/post/7256703802023493687
评论
请登录