React的核心为组件。你可以像嵌套HTML标签一样嵌套使用这些组件,这使得编写JSX更加容易因为它类似于标记语言。

当我刚开始学习React时,当时我认为“使用 props.children 就这么回事,我知道它的一切”。我错了。。

因为我们使用的事JavaScript,我们会改变children。我们能够给它们发送特殊的属性,以此来决定它们是否进行渲染。让我们来探究一下React中children的作用。

子组件

我们有一个组件 <Grid /> 包含了几个组件 <Row /> 。你可能会这么使用它:

<Grid>
<Row />
<Row />
<Row />
</Grid>

这三个 Row 组件都成为了 Gridprops.children 。使用一个表达式容器,父组件就能够渲染它们的子组件:

class Grid extends React.Component {
render() {
return <div>{this.props.children}</div>
}
}

父组件也能够决定不渲染任何的子组件或者在渲染之前对它们进行操作。例如,这个 <Fullstop /> 组件就没有渲染它的子组件:

class Fullstop extends React.Component {
render() {
return <h1>Hello world!</h1>
}
}

不管你将什么子组件传递给这个组件,它都只会显示“Hello world!”

任何东西都能是一个child

React中的Children不一定是组件,它们可以使任何东西。例如,我们能够将上面的文字作为children传递我们的 <Grid /> 组件。

<Grid>Hello world!</Grid>

JSX将会自动删除每行开头和结尾的空格,以及空行。它还会把字符串中间的空白行压缩为一个空格。

这意味着以下的这些例子都会渲染出一样的情况:

<Grid>Hello world!</Grid>

<Grid>
Hello world!
</Grid> <Grid>
Hello
world!
</Grid> <Grid> Hello world!
</Grid>

你也可以将多种类型的children完美的结合在一起:

<Grid>
Here is a row:
<Row />
Here is another row:
<Row />
</Grid>

child 的功能

我们能够传递任何的JavaScript表达式作为children,包括函数。

为了说明这种情况,以下是一个组件,它将执行一个传递过来的作为child的函数:

class Executioner extends React.Component {
render() {
// See how we're calling the child as a function?
// ↓
return this.props.children()
}
}

你会像这样的使用这个组件

<Executioner>
{() => <h1>Hello World!</h1>}
</Executioner>

当然,这个例子并没什么用,只是展示了这个想法。

假设你想从服务器获取一些数据。你能使用多种方法实现,像这种将函数作为child的方法也是可行的。

<Fetch url="api.myself.com">
{(result) => <p>{result}</p>}
</Fetch>

不要担心这些超出了你的脑容量。我想要的是当你以后遇到这种情况时不再惊讶。有了children什么事都会发生。

操作children

如果你看过React的文档你就会说“children是一个不透明的数据结构”。从本质上来讲, props.children 可以使任何的类型,比如数组、函数、对象等等。

React提供了一系列的函数助手来使得操作children更加方便。

循环

两个最显眼的函数助手就是 React.Children.map 以及 React.Children.forEach 。它们在对应数组的情况下能起作用,除此之外,当函数、对象或者任何东西作为children传递时,它们也会起作用。

class IgnoreFirstChild extends React.Component {
render() {
const children = this.props.children
return (
<div>
{React.Children.map(children, (child, i) => {
// Ignore the first child
if (i < 1) return
return child
})}
</div>
)
}
}

<IgnoreFirstChild /> 组件在这里会遍历所有的children,忽略第一个child然后返回其他的。

<IgnoreFirstChild>
<h1>First</h1>
<h1>Second</h1> // <- Only this is rendered
</IgnoreFirstChild>

在这种情况下,我们也可以使用 this.props.children.map 的方法。但要是有人讲一个函数作为child传递过来将会发生什么呢?this.props.children 会是一个函数而不是一个数组,接着我们就会产生一个error!

 
err

然而使用 React.Children.map 函数,无论什么都不会报错。

<IgnoreFirstChild>
{() => <h1>First</h1>} // <- Ignored

对React children 的深入理解的更多相关文章

  1. React源码 React.Children

    children是什么意思呢?就是我们拿到组件内部的props的时候,有props.children这么一个属性,大部分情况下,我们直接把 props.children 渲染到 JSX 里面就可以了. ...

  2. react第十单元(children的深入用法-React.Children对象上的方法)

    第十单元(children的深入用法-React.Children对象上的方法) #课程目标 理解什么是children 掌握React.Children对象上的方法 #知识点 什么是children ...

  3. React中JSX的理解

    React中JSX的理解 JSX是快速生成react元素的一种语法,实际是React.createElement(component, props, ...children)的语法糖,同时JSX也是J ...

  4. React中props.children和React.Children的区别

    在React中,当涉及组件嵌套,在父组件中使用props.children把所有子组件显示出来.如下: function ParentComponent(props){ return ( <di ...

  5. React.Children详解

    React.Children提供了处理this.props.children的工具,this.props.children可以任何数据(组件.字符串.函数等等).React.children有5个方法 ...

  6. react children技巧总结

    在使用该技巧时,建议先看一下相关的知识,点我查看 假如使用该属性时,想把父组件的所有属性及部分方法传递给子组件,该怎么办呢?看代码 const Child = ({ doSomething, valu ...

  7. [React] Compound Component (React.Children.map & React.cloneElement)

    Imaging you are building a Tabs component. If looks like: <Tabs> <TabList> <Tab> o ...

  8. [React] Understand React.Children Utilities

    The data contained in this.props.children is not always what you might expect. React provides React. ...

  9. React: 通过React.Children访问特定子组件

    一.简介 React中提供了很多常用的API,其中有一个React.Children可以用来访问特定组件的子元素.它允许用来统计个数.map映射.循环遍历.转换数组以及显示指定子元素,如下所示: va ...

随机推荐

  1. 打包dll发布到nuget服务器

    几个月前上传过一次nuget包,结果好久不用,今天想更新下,完全忘记了怎么用了,又是一顿查,所以决定记录下来,当然这可能不是一个傻瓜式的教程,但聪明的你们应该能够看明白的,因为整体操作还是很简单的 好 ...

  2. 说说Javac

    Java语言有Java语言的规范,,这个规范详细描述了Java语言有哪些词法.语法,而Java虚拟机也有其Java虚拟机的规范,同样Java虚拟机的规范和Java语言规范并不一样,它们都有自己的词法和 ...

  3. [转]SVN服务器搭建和使用(二)

    上一篇介绍了VisualSVN Server和TortoiseSVN的下载,安装,汉化.这篇介绍一下如何使用VisualSVN Server建立版本库,以及TortoiseSVN的使用. 首先打开Vi ...

  4. P1776 宝物筛选_NOI导刊2010提高(02)

    题目描述 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物.看来小FF只能含泪 ...

  5. Tensorflow-slim 学习笔记(一)概述

    TF-Slim的优势:slim作为一种轻量级的tensorflow库,使得模型的构建,训练,测试都变得更加简单. 1. 使用方法: import tensorflow.contrib.slim as ...

  6. struts2第一天——入门和基本操作

    一.概述 1.运用场景: 应用于三层架构中web层的框架(显示层的运用),是经典MVC模型的web应用的变体. 2.与struts1的对比: struts2是在struts1基于webwork发展的全 ...

  7. rabbitmq的安装和使用

    一.RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件).RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的.所有 ...

  8. jquery几秒钟之后跳转页面

    <script> window.onload = function() { var el = document.getElementById('js-tip-timer'), i = 5; ...

  9. 原来new的java对象不是所有的都存在堆内存

    JVM在晚期(运行期)优化时,使用到一种技术----逃逸分析. 补充说明:逃逸分析在1999年就已提出,但是JDK1.6才实现逃逸分析.而且,这项优化目前仍不成熟,仍有很大改进余地. 这是大坑啊,目前 ...

  10. Linux之linux基础命令2

    目录相关: 创建目录: mkdir 目录名 递归创建a/b c/d: mkdir -p a/b c/d 递归创建test/a,b,c,d四个目录: mkdir - p test{a,b,c,d} 递归 ...