React文档(十四)深入JSX
根本上,JSX只是为React.createElement(component, props, ...children)函数提供语法糖。JSX代码是这样的:
<MyButton color="blue" shadowSize={2}>Click Me </MyButton>
编译成这样:
React.createElement(MyButton,{color: 'blue', shadowSize: 2},'Click Me' )
你也可以使用自己闭合的标签块如果它们没有子元素。
<div className="sidebar" />
编译成这样:
React.createElement('div',{className: 'sidebar'},null )
如果你想要测试JSX是怎样转换成js的,你可以试一试在线Babel编译器。
指定react元素类型
JSX标签名决定了React元素的类型。
首字母大写的类型表明JSX标签涉及到一个React组件。这些标签被编译成同名变量并被引用,因此如果你使用JSX <Foo />表达式,必须在作用域之内声明Foo变量。
React必须声明
import React from 'react'; import CustomButton from './CustomButton';function WarningButton() {// return React.createElement(CustomButton, {color: 'red'}, null);return <CustomButton color="red" />; }
如果你不使用一个js打包器而是把React以一个script标签添加,那么React就已经在作用域内,作为一个全局对象。
点表示法
你也可以在JSX中使用点号来引用一个React组件。如果你有一个单独模块导出了很多React组件,这样就很方便。举个例子,如果MyComponents.DatePicker是一个组件,你可以在JSX中直接使用它。
import React from 'react';const MyComponents = {DatePicker: function DatePicker(props) {return <div>Imagine a {props.color} datepicker here.</div>; } }function BlueDatePicker() {return <MyComponents.DatePicker color="blue" />; }
用户定义组件必须首字母大写
import React from 'react';// 错误!组件名应该首字母大写: function hello(props) {//正确,div是有效的html标签:return <div>Hello {props.toWhat}</div>; }function HelloWorld() {// 错误!React 会将小写开头的标签名认为是 HTML 原生标签:return <hello toWhat="World" />; }
为了解决这个问题,我们会重命名hello为Hello并且在渲染的时候使用<Hello />。
import React from 'react';// 正确!组件名应该首字母大写: function Hello(props) {// 正确,div是有效的html标签:return <div>Hello {props.toWhat}</div>; }function HelloWorld() {// 正确!React 能够将大写开头的标签名认为是 React 组件.return <Hello toWhat="World" />; }
运行时选择类型
import React from 'react'; import { PhotoStory, VideoStory } from './stories';const components = {photo: PhotoStory,video: VideoStory };function Story(props) {// 错误!JSX 标签名不能为一个表达式.return <components[props.storyType] story={props.story} />; }
修复这个问题,我们会在一开始指派类型给一个首字母大写的变量:
import React from 'react'; import { PhotoStory, VideoStory } from './stories';const components = {photo: PhotoStory,video: VideoStory };function Story(props) {// 正确!JSX 标签名可以为大写开头的变量.const SpecificStory = components[props.storyType];return <SpecificStory story={props.story} />; }
JSX里的props
有许多不同的方法在JSX里指定props。
js表达式
你可以将任意js表达式作为一个prop来传递,通过用{}包裹表达式。举个例子,在这段JSX里:
<MyComponent foo={1 + 2 + 3 + 4} />
对于MyComponent,props.foo的值会是10因为表达式1+2+3+4被求值了。
if语句和for循环在js里不算表达式,所以他们在JSX里不能直接使用。另外,你可以把它们放在周围的代码里。举个例子:
function NumberDescriber(props) {let description;if (props.number % 2 == 0) {description = <strong>even</strong>;} else {description = <i>odd</i>; }return <div>{props.number} is an {description} number</div>; }
字符串常量
你可以将一个字符串作为一个prop来传递。下面两个JSX表达式是相等的:
<MyComponent message="hello world" /><MyComponent message={'hello world'} />
当你传递了一个字符串字面值,该值会被解析为HTML非转义字符串。所以下面两个JSX表达式是相等的:
<MyComponent message="<3" /><MyComponent message={'<3'} />
这个行为通常不是有重大意义的,这里提及只是因为完整性。
props默认是true
如果你不给prop传递任何值,那么它默认就是true。下面两个JSX表达式是相等的:
<MyTextBox autocomplete /><MyTextBox autocomplete={true} />
通常情况下,我们不建议使用这个因为ES6对象简洁表示法会造成困惑。{foo}是{foo: foo}的简写形式而不是{foo: true}。这里这样用是因为这个行为和HTML的行为匹配。
扩展属性
如果你已经有了一个对象props,并且你想要把它传递给JSX,你可以使用...扩展运算符来传递整个props对象。下面两个组件是等同的:
function App1() {return <Greeting firstName="Ben" lastName="Hector" />; }function App2() {const props = {firstName: 'Ben', lastName: 'Hector'};return <Greeting {...props} />; }
扩展属性当你在创建通用容器的时候会很有用。然而,他们也会把你的代码弄乱,因为它们很容易传递很多不相关的props给根本不关心它们的组件。我们建议你保守地使用此语法。
JSX里的children
在同时包含起始标签和结束标签的JSX表达式里,这些标签之间的内容被作为特殊的prop来传递:props.children。传递children有几种不同的方式:
字符串常量
你可以在起始标签和结束标签之间放一个字符串props.children。这对于许多内建HTML元素来说很有用。举个例子:
<MyComponent>Hello world!</MyComponent>
这是有效的JSX,而且MyComponent组件的props.children就是那个字符串“Hello world!”。HTML未转义,所以你可以像写HTML一样来写JSX:
<div>This is valid HTML & JSX at the same time.</div>
JSX会移除一行开头的空格和结尾的空格。它也会移除空行。临近标签的新行被移除;字符串字面量中间出现的新行会被压缩成一个空格。所以下面的都会被渲染成一样的:
<div>Hello World</div><div>Hello World </div><div>HelloWorld </div><div>Hello World </div>
JSX children
你可以提供更多的JSX元素来作为子元素。这样在显示嵌套的组件时会很有用:
<MyContainer><MyFirstComponent /><MySecondComponent /> </MyContainer>
你也可以混合不同类型的子元素,所以你可以将JSX子组件和字符串字面量一起使用。这样使JSX像HTML的语法,就可以同时使JSX和HTML都有效:
<div>Here is a list:<ul><li>Item 1</li><li>Item 2</li></ul> </div>
React 组件也可以通过数组的形式返回多个元素:
render() {// 不需要使用额外的元素包裹数组中的元素return [// 不要忘记 key :)<li key="A">First item</li>,<li key="B">Second item</li>,<li key="C">Third item</li>, ]; }
js表达式
你可以传递任意js表达式作为子元素,通过使用{}来包裹表达式。举个例子,以下表达式是等同的:
<MyComponent>foo</MyComponent><MyComponent>{'foo'}</MyComponent>
function Item(props) {return <li>{props.message}</li>; }function TodoList() {const todos = ['finish doc', 'submit pr', 'nag dan to review'];return (<ul>{todos.map((message) => <Item key={message} message={message} />)}</ul> ); }
js表达式可以与其他类型子元素混合。这样在字符串模板的场景里比较常用:
function Hello(props) {return <div>Hello {props.addressee}!</div>; }
函数作为子元素
// Calls the children callback numTimes to produce a repeated component function Repeat(props) {let items = [];for (let i = 0; i < props.numTimes; i++) {items.push(props.children(i));}return <div>{items}</div>; }function ListOfTenThings() {return (<Repeat numTimes={10}>{(index) => <div key={index}>This is item {index} in the list</div>}</Repeat> ); }
给自定义组件传递的children可以是任何东西,只要组件在渲染之前将它们转变成React可以理解的即可。这个children的用法不常见,但是它是可以运行的只要你想要扩展JSX的能力。
布尔值,null值还有undefined是被忽略的
<div /><div></div><div>{false}</div><div>{null}</div><div>{undefined}</div><div>{true}</div>
这样根据条件是否渲染React元素就可以很有用。下面JSX渲染一个<Header />如果showHeader的值是true:
<div>{showHeader && <Header />}<Content /> </div>
值得注意的就是一些会被转换成false的值,类似于数字0,依然会被React渲染。举个例子,下面的代码也许不会像你期待的那样运行因为当props.messages是一个空数组的时候0将会被打印:
<div>{props.messages.length &&<MessageList messages={props.messages} /> } </div>
<div>{props.messages.length > 0 &&<MessageList messages={props.messages} /> } </div>
相反的,如果你想要让一个值像false,true,null或者undefined出现在输出中,你必须首先将它转换成字符串:
<div>My JavaScript variable is {String(myVariable)}. </div>
转载于:https://www.cnblogs.com/hahazexia/p/6428011.html
React文档(十四)深入JSX相关推荐
- Android 系统 (130)---ODM 开发用户常见需求文档(四)
ODM 开发用户常见需求文档(四) 一:取消用户模式 (frameworks/) diff --git a/base/packages/SystemUI/res/layout/keyguard_sta ...
- 《信息化项目文档模板四——系统建设方案模板》
系列文章目录 <信息化项目文档模板一--项目需求说明书> <信息化项目文档模板二--项目启动会文档模板> <信息化项目文档模板三--会议纪要模板> <信息化项 ...
- PPT转成Word文档的四种方法
注: 实际使用中,方法四比较好使. 如果想要提取图片,可以先转换成pdf,再转换成word. 方法一:利用"大纲"视图 打开PPT演示文稿,单击"大纲&quo ...
- Javadoc转换chm帮助文档的四种方法总结
使用jd2chm.exe方式无法完成,不晓得为什么. 所以用的javadoc2chm 方式,但是chm文档开头AllClass乱码, 用chmeditor修改就可以了 点击Files 下的工具类文档. ...
- 【大运维之四】运维标准化文档的四项基本原则
http://www.csdn.net/article/2015-08-12/2825444 [大运维之四]运维标准化文档的四项基本原则 发表于 2015-08-12 11:03| 534次阅读| ...
- React文档(一)安装
React是一个灵活的可以用于各种不同项目的框架,你可以用它来写新应用,你也可以逐步将它引进已有的代码库而不用重写整个项目. 试用React 如果你想玩一玩React,那么就去CodePen上试一试. ...
- 服务器测评文档,十年磨一剑,腾讯自研TBase数据库有奖测评
[TBase开源版测评]征文活动获奖名单公布:https://cloud.tencent.com/developer/article/1691427 TBase是 7月13日,TBase重磅发布了开源 ...
- 盘点PDF文件转Word文档的四种高效率转换方法
随着PDF文件的广泛使用,PDF文件已经作为正式文件进行传输.但大多的人还是偏向于用Word进行编辑,对于手头上的PDF文件束手无策.不用怕,今天小编就来解救大家.经过小编亲身实践的几个关于PDF转换 ...
- Word文档的四种加密方法
word文件大家都很熟悉,文件加密方式也有很多种,今天和大家分享四种word文档的加密方式: 第一种:打开密码 给word文档设置打开密码,可以保护word文档不被人查看,只有在打开word文件的时候 ...
- Python Scapy(2.3.1)文档学习(四):高级用法
ASN.1和SNMP 什么是ASN.1 ? 注意:这只是我对ASN.1的个人观点,我会尽可能的做简单的解释.至于更多的理论或者学术观点,我相信你会在互联网上找到更好的. ASN.1(抽象语法标记)是一 ...
最新文章
- ZooKeeper的事务日志和快照
- 设计模式复习-简单工厂模式
- Linux Shell常用技巧(七)
- python求球的表面积_892. 三维形体的表面积(Python)
- 年底绝对不能犯的四个职场错误
- 在python中分析药品销售数据
- 【团队技术知识分享 一】技术分享规范指南
- 美团java后端_美团笔试题(Java后端5题2小时)(示例代码)
- 什么牌子的降噪耳机好用又实惠?平价好用的蓝牙耳机推荐
- 全球与中国医疗3D打印机市场深度研究分析报告
- 利用dns特性把普通域用户提升到域管理员权限
- ligerui 表格滚动条放在表格里,固定表头
- 关于用GetDIBits代替GetPixel效率低的问题
- Js获取字符串asc码
- Android基础知识【项目实训-实现二级导航“今日活动”及读取数据库】【5】
- 国内如何打开 Coursera?(Mac系统)
- Android使用Google SMSRetrieverAPI监听短信
- hdu6217 - BBP Formula
- python程序员辛苦吗-令人羡慕!33岁程序员晒出收入和待遇,网友望尘莫及
- BBC iPlayer Downloads for Mac(英剧下载器)
热门文章
- java青蛙青蛙跳井_公务员行测技巧:青蛙跳井问题
- android将拦截短信通过邮箱发送,网易邮箱Android客户端推出 加速布局移动互联网...
- pptv网络电视android,PP视频(原聚力视频)
- matlab 多条函数颜色渐变(没多大用处)
- Replication Controller、Replica Set
- scala学习笔记-面向对象编程之Trait
- 【深度学习篇】--Windows 64下tensorflow-gpu安装到应用
- 对java多线程里Synchronized的思考
- 5G推进阻力大 面临多利益方博弈
- Django学习笔记 开发环境搭建