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的灵 ...
随机推荐
- Cordova Upload Images using File Transfer Plugin and .Net core WebAPI
In this article, I am going to explain ,"How to Upload Images to the server using Cordova File ...
- UNION的使用方法 (表与表直接数据和在一起的示例)
SELECT o.CATEGORY CATEGORY,o.KEY_WORK KEY_WORK FROM BO_EU_KEY_WORK wo RIGHT OUTER JOIN BO_EU_WORK_ON ...
- <TCP/IP原理> (三) 底层网络技术
传输介质 局域网(LAN) 交换(Switching) 广域网(WAN) 连接设备 第三章 底层网络技术 引言 1)Interne不是一种新的网络 建立在底层网络上的网际网 底层网络——“物理网”,网 ...
- [pip]upgrade outdated pip package on windows / 在windows上更新所有过时的pip包
首先更新pip自身: python -m pip install -U pip 查询过期包: pip list --outdated --format=columns Package Version ...
- Vue 报错[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders
场景:父组件向子组件传递数据,子组件去试图改变父组件数据的时候. 解决:子组件通过事件向父组件传递信息,让父组件来完成数据的更改. 比如:我的父组件是普通页面,子组件是弹窗的登录界面,父组件传递的数据 ...
- EC20 R2.1
1.模块开机成功前WAKEUP_IN. NET_MODE. BT_CTS. COEX_UART_TX(背部焊盘). COEX_UART_RX(背部焊盘) 和WLAN_EN(背部焊盘)引脚禁止上拉. 2 ...
- 第四周博客作业<西北师范大学|李晓婷>
1.助教博客链接:https://home.cnblogs.com/u/lxt-/ 2.作业要求链接:www.cnblogs.com/nwnu-daizh/p/10487329.html 3.本周点评 ...
- WebDriver下载地址
http://chromedriver.storage.googleapis.com/index.html https://blog.csdn.net/ccggaag/article/details/ ...
- 编写高质量的Python代码系列(六)之内置模块
Python预装了许多写程序时会用到的重要模块.这些标准软件包与通常意义上的Python语言联系得非常精密,我们可以将其当成语言规范的一部分.本节将会讲解基本的内置模块. 第四十二条:用functoo ...
- R语言入门(1)-初识R语言
设置R语言环境为英文环境 其实不设置也行...就是报错提示的内容是中文的话, 会不太好理解.. 1. 首先在用户根目录下cat查看一下, 发现没有.Renviron文件, 这个是R语言的环境配置文件. ...