对React children 的深入理解
React的核心为组件。你可以像嵌套HTML标签一样嵌套使用这些组件,这使得编写JSX更加容易因为它类似于标记语言。
当我刚开始学习React时,当时我认为“使用 props.children 就这么回事,我知道它的一切”。我错了。。
因为我们使用的事JavaScript,我们会改变children。我们能够给它们发送特殊的属性,以此来决定它们是否进行渲染。让我们来探究一下React中children的作用。
子组件
我们有一个组件 <Grid /> 包含了几个组件 <Row /> 。你可能会这么使用它:
<Grid>
<Row />
<Row />
<Row />
</Grid>
这三个 Row 组件都成为了 Grid 的 props.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!

然而使用 React.Children.map 函数,无论什么都不会报错。
<IgnoreFirstChild>
{() => <h1>First</h1>} // <- Ignored
对React children 的深入理解的更多相关文章
- React源码 React.Children
children是什么意思呢?就是我们拿到组件内部的props的时候,有props.children这么一个属性,大部分情况下,我们直接把 props.children 渲染到 JSX 里面就可以了. ...
- react第十单元(children的深入用法-React.Children对象上的方法)
第十单元(children的深入用法-React.Children对象上的方法) #课程目标 理解什么是children 掌握React.Children对象上的方法 #知识点 什么是children ...
- React中JSX的理解
React中JSX的理解 JSX是快速生成react元素的一种语法,实际是React.createElement(component, props, ...children)的语法糖,同时JSX也是J ...
- React中props.children和React.Children的区别
在React中,当涉及组件嵌套,在父组件中使用props.children把所有子组件显示出来.如下: function ParentComponent(props){ return ( <di ...
- React.Children详解
React.Children提供了处理this.props.children的工具,this.props.children可以任何数据(组件.字符串.函数等等).React.children有5个方法 ...
- react children技巧总结
在使用该技巧时,建议先看一下相关的知识,点我查看 假如使用该属性时,想把父组件的所有属性及部分方法传递给子组件,该怎么办呢?看代码 const Child = ({ doSomething, valu ...
- [React] Compound Component (React.Children.map & React.cloneElement)
Imaging you are building a Tabs component. If looks like: <Tabs> <TabList> <Tab> o ...
- [React] Understand React.Children Utilities
The data contained in this.props.children is not always what you might expect. React provides React. ...
- React: 通过React.Children访问特定子组件
一.简介 React中提供了很多常用的API,其中有一个React.Children可以用来访问特定组件的子元素.它允许用来统计个数.map映射.循环遍历.转换数组以及显示指定子元素,如下所示: va ...
随机推荐
- virtualbox+vagrant学习-2(command cli)-24-Aliases别名
Aliases 别名的部分灵感来自Git自身的别名功能,它允许你创建自己的定制vagrant命令,从而使你的vagrant体验更简单.更容易.更熟悉. 别名可以在VAGRANT_HOME/ alias ...
- php5.6+Apache2.4+MySQL
在配置php的时候可以直接使用集成环境XAMPP:https://bitnami.com/stack/xampp?utm_source=bitnami&utm_medium=installer ...
- Angular动态表单生成(七)
动态表单生成之拖拽生成表单(上) 这个功能就比较吊炸天了,之前的六篇,都是ng-dynamic-forms自带的功能,可能很多的说明官方的文档都已经写了,我只是个搬运工,而在这篇文章中,我将化身一个工 ...
- aps.net mvc webapi 实现文件或图片上传
前几天看到网上有很多复杂的实现方式,觉得没必要,所以就写个简单的实现. 一:首先来看看Api Controller里面的代码: HttpContext.Current.Request.Files 这 ...
- MySQL数据库初始
MySQL数据库 本节目录 一 数据库概述 二 MySQL介绍 三 MySQL的下载安装.简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 初识sql语句 一 ...
- head 标签里有什么?
head 标签里有什么? 每一个 HTML 文档中,都有一个不可或缺的标签:<head> ,它作为一个容器,主要包含了用于描述 HTML 文档自身信息(元数据)的标签,这些标签一般不会在页 ...
- 20145226 2016-2017-2 夏艺华 《Java程序设计》 课程总结
20145226夏艺华 <Java程序设计>课程总结 每周读书笔记链接汇总 第一周读书笔记 了解Java编程风格,认识Java的类型与变量,掌握Java流程控制的方法(分支.循环). ht ...
- JavaWeb总结(十)
Filter配置详解 web项目目录示意图 <!-- Filter配置 --> <filter> <display-name>Filter_one</disp ...
- PostgreSQL timeline
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL基础知识与基本操作索引页 回到顶级页面:PostgreSQL索引页 关于timeline,有如下的说法 http ...
- 05- views视图层
1.配置index 主url from django.contrib import admin from django.urls import path, re_path, include urlpa ...