博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过 JSX Control Statements 编写 JSX
阅读量:6785 次
发布时间:2019-06-26

本文共 3162 字,大约阅读时间需要 10 分钟。

通过 JSX Control Statements 编写 JSX

一、前言

一些开发者,特别是有使用过「模板技术」的开发者(例如 Handlebars),刚开始尝试使用 React 编写应用时,可能会惊讶的发现,JSX 竟然没有内建支持类似其它模板引擎似的任何结构控制语句或指令。但这就是 JSX,它就是这么设计的,JSX 不是传统的模板,也不需要某个模板引擎去解析。大体上,可以将 JSX 看成普通 JavaScript 表达式的语法糖。

下边的的代码是一个「普通的 JavaScript 代码示例」

render () {  return (if(true){    ...  }else{    ...  });}

如上代码不合法的,同样,下边的 jsx 代码也是不合法的

render () {  return (
{if(true)
1 else
2 }
);}

因为,JavaScript 不能在一个「表达式」中嵌入「控制语句」。

二、能做什么?

JSX-Control-Statements 为 JSX 增加了基本的结构控制语句,比如条件和循环控制语句。通过将插件将「组件风格」的控制语句最终转换为普通 JS 代码,例如:

Hello World!

将会转换为

condition() ? 'Hello World!' : null

三、实现原理及说明

这看起来,似乎很容易实现,通过一系列表组件好像就能实现,但事实上这在 React 中这是不可行的,如果用「组件」的方式实现,类似如下代码

  • {item.title}

组件的方式实现上边的代码,将会抛出来一个错误 Cannot read property 'title' of undefined

因为 React 在执行到 ForComponent 时就是会执行它的 children ,想达到目的,需要延后执行 FormComponent 的 children,那么只能用一个 function 包裹,并在这个函数中返回 jsx 表达式,但这将比直接写 map 方法还麻烦。

所以,JSX Control Statements 是一个 Babel 插件,采取了在「编译阶段」将「控制标签」转换为「普通的 JavaScript 表达式」的方案,最终编译结果和原来的写法没有什么不同。

四、安装

需要先行安装好 Babel,之后通过 npm 安装 jsx-control-statements

npm install --save-dev jsx-control-statements

还需要在 .babelrc 中配置插件,如下

{  ...  "plugins": ["jsx-control-statements"]}

五、核心语法

If 标签

用来表示最简单的条件判断逻辑

// 简单示例
IfBlock
// 包括多个子元素及表达式
one { "two" }
three
four

<If>

if 的 body 部分只有在 condition 为 true 才会渲染

属性名 类型 必须
condition boolean

<Else /> (deprecated)

Eles 已废弃,不推荐使用,它会破坏 JSX/XML 的语法,并且影响自动格式化。

转换

If 标签将会预编译为「三元表达式」

// 转换前
Truth
// 转换后{ test ? Truth : null }

Choose 标签

Choose 是比 If 更复杂分支结构写法

IfBlock
ElseIfBlock
Another ElseIfBlock
...
ElseBlock
// default block is optional; minimal example:
IfBlock

<Choose>

Choose 的子元素只允许出现 WhenOtherwise,其中最少需要有一个 When,而 Otherwise 是可选的

<When>

<If> 类似

属性名 类型 必须
condition boolean

<Otherwise>

没有任何一个 When 满足条件时,将会渲染 Otherwise

转换

Choose 标签同样将会预编译为「三元表达式」

// 转换前
IfBlock1
IfBlock2
ElseBlock
// 转换后{ test1 ? IfBlock1 : test2 ? IfBlock2 : ElseBlock }

For 标签

For 的命名用方法,如下

// 注意,需要指定 key 属性  
{ item.title }
{ item }
Static Text
属性名 类型 必须 说明
of Array/collection 列表或包含 map 方法的集合
each string 循环「项」变量名
index string 循环「索引」变量名

注意,For 不能作为根元素

转换

// 转换前
{ index }. { item.title }
// 转换前{ items.map( function(item, index) { { index }. { item.title } })}

With 标签

用于将值赋给局部变量

// 简单用法
{ foo }
{ bar }
// 嵌套使用
{ foo }
{ bar }
属性名 类型 必须 说明
any any 将值赋给指定名称的局部变量

注意,定义的「变量」仅在 With 块中可用。

转换

<With> 将会转换为一个「匿名的立即执行函数」

// 转换前
{ foo }
// 转换后{ (function(foo) { return { foo } }).call(this, 47)}

六、对比普通 JS/JSX 写法的对比

带来的好处

  • 更直观、对于习惯于模板语法的开发人员或设计人员,更接近于传统模板写法
  • 减少 JS/JSX 相互隔断导致的代码「支离破碎」
  • 更好的可读性和整洁,不过这取决于你的个人喜好。

一点小问题

  • 多了一步编译,会多用一点点构建时间
  • 依赖 Bable 6,并需要配置一下 .babelrc

七、如何进行语法检查?

ESLint

所有结构控制标签都是通过 Babel 插件进行转义的, 不需要 require or import,所有在进行「语法检查」时,将会出现「变量未定义」的警告或错误。

但是,有一个 ESlint 插件可处理这个问题

-- end --

转载地址:http://ugdgo.baihongyu.com/

你可能感兴趣的文章
企业VLAN配置实例
查看>>
JPush极光推送Java服务器端实例
查看>>
trie 转载(来源于http://www.cnblogs.com/njuzyc/archive/2012/01/25/2329332.html)
查看>>
Office提示由于本机的限制该操作已被取消怎么办
查看>>
Google Earth网页版初探
查看>>
Mysql数据库连接池知识分享
查看>>
SpringMVC 拦截请求,判断会话是否超时
查看>>
网站前端_KindEditor.基础入门.0001.KindEditor_3.4.2快速入门?
查看>>
android拍照并通过Http发送到Java后台
查看>>
ubuntu安装nginx-1.8.0.tar.gz
查看>>
魔兽争霸3地图(WarIII Maps):妖皇传说
查看>>
grub2正确配置——硬盘安装ubuntu 9.10之后不能启动xp解决方法
查看>>
PHP isset()与empty()的使用区别详解
查看>>
mysql 修改数据库的时区
查看>>
MyBatis 通过包含的jdbcType类型
查看>>
Web应用中的中文问题
查看>>
with as 中绑定变量的使用
查看>>
时间:2014年4月8日17:01:10 GD完成验证码
查看>>
mysql主从同步
查看>>
微信机器人高级版常见问题汇总
查看>>