对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 ...
随机推荐
- 【转】纯JS省市区三级联动(行政区划代码更新至2015-9-30)
本文代码实现的功能是省市区三级联动下拉列表,纯Javascript,网上已有很多这方面的代码.但是作为一个新手,这是我的第一篇CSDN博客,发此文的目的主要是学习交流,希望看到的朋友发现有什么不对的地 ...
- 【转】python中的对象拷贝
转自:https://www.cnblogs.com/bhlsheji/p/5352330.html python中.进行函数參数传递或者返回值时,假设是一般的变量,会拷贝传递.假设是列表或字典则是引 ...
- 创建ROS工程結構
图像化显示目录工程结构:tree $ sudo apt install tree 1.创建ROS工作空间 $ mkdir -p catkin_ws/src # Create mutil-level d ...
- 【ThinkingInC++】75、多重继承
第九章 多重继承 9.2 接口继承 Intertfacees.cpp /** * 书本:[ThinkingInC++] * 功能:接口继承Interfaces.cpp * 时间:2014年10月28日 ...
- 【jq】插件—弹出层layer.js
layer.js包含了所有的层级情形,并且附加的有:tab层,相册层.webIM层. 适用于移动版本的layer.js 为layer for mobile 配套的layui 非常适合用于后台系统的 ...
- Windows全版本KMS激活脚本
搭建了个KMS服务器,制作了个批处理激活脚本,所有代码可以看到,让你再也不用担心系统会被有些激活工具强改主页,留有后门的风险了. 本脚本可以激活Windows全版本,安全.绿色. 1.首先你的系统必须 ...
- 20155239 2017-11-19 实现mypwd(选做,加分)
20155239 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...
- RabbitMQ(四):RPC的实现
原文:RabbitMQ(四):RPC的实现 一.RPC RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. ...
- iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字
iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字 简述:NSString * regex_0 = @"\\d{1,}"; /*允许首位为0*/ NSString * re ...
- noip2017 PJ AK记
嗨小朋友们大家好,还记得我是谁吗?我就是为RE代言的蒟蒻--xzz day1 蛤?四楼只有一个考场???在逗我 然后解压 蛤?空军68年????我怎么不知道???huaji 蛤?T1这么sb?切掉 蛤 ...