JSX的替代方案(译文)
原文链接:https://blog.bloomca.me/2019/02/23/alternatives-to-jsx.html
JSX作为一种流行的模板语言,在各种框架都得到了广泛的应用。但是,如果您不喜欢它,或者您想在某个项目中使用其他的方案,或者只是想知道如何在没有它的情况下编写React代码,最简单的答案是阅读官方文档,不过它有点过于精简了。
什么是JSX?
首先,我们需要知道JSX是什么,以便知道其翻译为纯JS是什么样的。JSX是一种特定领域的语言,这意味着我们需要使用JSX转换器以获得常规JS代码,否则浏览器将无法识别。如果在未来,浏览器能够支持JSX的所有特性,而我们仍然没有扔掉转换器,这可能就是一个问题了。
JSX转换示例:
class A extends React.Component {
render() {
return (
<div className={"class"} onclick={some}>
{"something"}
<div>something else</div>
</div>
)
}
}
转换为JS代码则是:
class A extends React.Component {
render() {
return React.createElement("div", {
className: "class",
onclick: some
}, "something", React.createElement("div", null, "something else"));
}
}
可以看到,所有标签都被React.createElement代替。其中,第一个参数可以是React组件或HTML标签字符串,第二个参数是标签属性,其他的参数则是内部children。
强烈推荐您花费一点时间,看一下React是如何用不同的方式,利用布尔值、数组、组件等去渲染它的属性的。即使您只使用JSX并对它相当满意,它也是有用的。
命名式
使用纯JS书写React代码是合法的也能够正确运行,但是,这种方式存在几种问题:
最突出的问题就是,它非常冗长,而冗长的罪魁祸首就是React.createElement语句。一个可见的解决方案就是将它保存到变量中,通常利用hyperscript语法命名为h,通过这种方式可以大幅度提高代码的简洁性和可读性。为更好的体现这一点,我们重写一下上面的代码:
const h = React.createElement;
class A extends React.Component {
render() {
return h(
"div",
{
className: "class",
onclick: some
},
"something",
h("div", null, "something else")
);
}
}
Hyperscript
如果你使用过React.createElement或h的任何一种方式,就知道它有一些缺陷。首先,它需要3个参数,当不存在这些参数时,就需要用null、className等一些常用的值去填充。
作为一种替代方案,你可以使用react-hyperscript库,这样就不用去填充多余的属性。并且,它还支持id和class的精简写法:div#main.content —> <div id="main" class="content">。这样一来,我们的代码就变成这样了:
class A extends React.Component {
render() {
return h("div.class", { onclick: some }, [
"something",
h("div", "something else")
]);
}
}
HTM
如果您不反对JSX本身,但是不喜欢编译代码,那么就可以使用htm作为替代方案。它的目标是做与JSX相同的事情(并且看起来相同),但是使用模板文字。这无疑增加了一些开销(运行时需解析模板),但在您的情况下,这可能是值得的。
它通过包装元素函数来工作,在我们的例子中是React.createElement。它可以是任何其他具有类似API的库,并返回一个函数,该函数将解析我们的模板,并返回与babel完全相同的代码,但只在运行时返回。
const html = htm.bind(React.createElement);
class A extends React.Component {
render() {
return html`
<div className=${"class"} onclick=${some}>
${"something"}
<div>something else</div>
</div>
`
}
}
正如上述代码所示,它与JSX非常相似,只是变量的插入方式稍有不同。不过,这些都是细节,如果您想展示如何在不需要任何工具的情况下使用React,这可能是一个很好的方式。
类Lisp语法
这个方法的思想类似于hyperscript,但是,作为一种优雅的实现方式,还是值得研究的。相关的类库有很多,可以选择一种进行实现,它可能会给你自己的项目带来灵感。
以库ijk为例,仅使用数组(使用位置作为参数)编写模板。主要的优点是你不需要不断地写h(React.createElement),下面是一个如何使用它的例子:
function render(structure) {
return h('nodeName', 'attributes', 'children')(structure)
}
class A extends React.Component {
render() {
return render([
'div', { className: 'class', onClick, some}, [
'something',
['div', 'something else']
]]);
}
}
结论
本文并没有说您不应该使用JSX,或者它是否是一个坏主意。但是,您可能想知道,没有它,您如何编写代码,您的代码可能是什么样子的,本文的目的只是回答这个问题。
相关文章:
Node.js Fundamentals: Web Server Without Dependencies
Metrics are Dangerous for Users
JSX的替代方案(译文)的更多相关文章
- CSS3魔法堂:CSS3滤镜及Canvas、SVG和IE滤镜替代方案详解
一.前言 IE特有的滤镜常常作为CSS3各种新特性的降级处理补充,而Adobe转向HTML5后与Chrome合作推出CSS3的Filter特性,因此当前仅Webkit内核的浏览器支持CSS3 F ...
- CSS3魔法堂:CSS3滤镜及Canvas、SVG和IE滤镜替代方案详解[转]
一.前言 IE特有的滤镜常常作为CSS3各种新特性的降级处理补充,而Adobe转向HTML5后与Chrome合作推出CSS3的Filter特性,因此当前仅Webkit内核的浏览器支持CSS3 F ...
- [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序处理并发
这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十篇:为ASP.NET MVC应用程序 ...
- MEAN实践——LAMP的新时代替代方案(上)
摘要:90 年代,LAMP 曾风靡一时,然而随着需求的变迁和数据流量的激增,LAMP 已不可避免的走下神坛.近日,在 MongoDB Blog 中,Dana Groce 介绍了一个基于新时代架构的实践 ...
- Ceph: A Scalable, High-Performance Distributed File System译文
原文地址:陈晓csdn博客 http://blog.csdn.net/juvxiao/article/details/39495037 论文概况 论文名称:Ceph: A Scalable, High ...
- 中文译文:Minerva-一种可扩展的高效的深度学习训练平台(Minerva - A Scalable and Highly Efficient Training Platform for Deep Learning)
Minerva:一个可扩展的高效的深度学习训练平台 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2015-12-1 声明 ...
- 每日一译系列-模块化css怎么玩(译文)
原文链接:How Css Modules Work 原文作者是Preact的作者 这是一篇关于如何使用Css Modules的快速介绍,使用到的工具是Webpack吊炸的css-loader 首先,我 ...
- 在Vue中使用JSX,很easy的
摘要:JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javasc ...
- Vue相关,Vue JSX
JSX简介 JSX是一种Javascript的语法扩展,JSX = Javascript + XML,即在Javascript里面写XML,因为JSX的这个特性,所以他即具备了Javascript的灵 ...
随机推荐
- C#给字符串赋予字面值——字符串插入、转义序列的使用
1.占位符.字符串插入 给字符串赋予字面值时,经常遇见在字符串中包含变量的情况,用连接符进行拼接.转换的方式比较麻烦.还容易出错.C#提供了较为便捷的处理方式,即‘占位符’,以及C#6的新功能‘插入字 ...
- Python视频人脸检测识别
案例 这里我们还是使用 opencv 中自带了 haar人脸特征分类器,通过读取一段视频来识别其中的人脸. 代码实现: 动图有点花,讲究着看吧: 如果是捕捉摄像头,只需要改变以下代码即可: c ...
- Vue.js 2.x笔记:状态管理Vuex(7)
1. Vuex简介与安装 1.1 Vuex简介 Vuex是为vue.js应用程序开发的状态管理模式,解决的问题: ◊ 组件之间的传参,多层嵌套组件之间的传参以及各组件之间耦合度过高问题 ◊ 不同状态中 ...
- 2019-04-05 Spring Boot学习记录
1. 使用步骤 ① 在pom.xml 增加父级依赖(spring-boot-starter-parent) ② 增加项目起步依赖,如spring-boot-starter-web ③ 配置JDK版本插 ...
- css的寬高約束
https://blog.csdn.net/qq_26780317/article/details/80736514
- hashlib 模块:加密
import hashlib # 基本使用 cipher = hashlib.md5('需要加密的数据的二进制形式'.encode('utf-8')) print(cipher.hexdigest() ...
- koa-static node服务器设置静态目录
最近毕设需要用到上传照片,但当node服务器成功获取前端传来的图片时,又不知道如何在页面获取服务器image目录下的图片,一直报以下错误: 问题主要是无法找到图片url,虽然可以一个个在app.js文 ...
- javaWeb2之Jsp
Java Server Page 放在除WEB-INF(放web项目的隐私文件)外的其他任何目录中. Java服务器端网页,实现在HTML页面编写Java代码实现动态内容,一种简化Servlet编写的 ...
- Go语言里的slice
1.切片是基于数组做的一层封装,灵活能够自动扩容. 2.切片的初始化方法 ①直接创建 ②基于已有的数组或切片 ③使用make来创建一个切片 第一个5是切片的大小 第二个5是切片的容量 3.基本操作 ① ...
- linux查看主板型号、CPU、显卡、硬盘等信息
系统 uname -a # 查看内核/操作系统/CPU信息 head -n 1 /etc/issue # 查看操作系统版本 cat /proc/cpuinfo # 查看CPU信息 hostname # ...