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的灵 ...
随机推荐
- rabbtimq非持久化测试
send端代码 import pika,time,threading class send(): def __init__(self,que_nam='hello'): self.credential ...
- 代理与hook
参考:Java 动态代理 代理是什么 为什么需要代理呢?其实这个代理与日常生活中的“代理”,“中介”差不多:比如你想海淘买东西,总不可能亲自飞到国外去购物吧,这时候我们使用第三方海淘服务比如惠惠购物助 ...
- jmetter的http请求设置
1.设置 cookie 2.设置header 3.login 4.post请求 5.get请求
- Django异步任务之Celery
Celery celery 是一个用于实现异步任务的库, 在很多项目中都使用它, 它和 django 融合使用很完美. 使用 celery 可以在实现 http request请求返回 view 前做 ...
- 【XSY3345】生成树 并查集
题目大意 有一个两部各有 \(n\) 个节点的二分图 \(G\),定义 \(G^m\) 为一个 \(m+1\) 层的图,每层有 \(n\) 个节点,相邻两层的诱导子图都和 \(G\) 相同. 给你 \ ...
- Linux 下 fcitx 崩溃
killall fcitx killall sogou-qimpanel fcitx & 输入以上命令
- GWAS群体分层校正,该选用多少个PCA
前言 关于选用多少个PCA做群体分层校正,各大期刊并没有一个统一的说法. 故做了如下综述. 1 随心所欲型,想选多少就选多少 PCA想选多少就选多少,这个真的不是开玩笑.有文献出处有真相! 比如下面文 ...
- Hexo next主题下添加天气插件
最近在优化hexo 新搭建的博客,想给博客添加一个天气插件,奈何找了很久也没发现,好不容易发现一个天气插件 心知天气:https://www.seniverse.com/widget/get 运气不好 ...
- freetypeLCD显示
目录 freetypeLCD显示 安装交叉编译环境 配置 头文件和库的位置 编译安装 复制到PC编译工具链 复制到文件系统 运行测试 LCD显示 编码转换问题 简单显示 角度旋转 换行显示 居中显示 ...
- checkbox 实现互斥选择
// mutex 互斥 checkbox 互斥/** 互斥的原理.找到需要互斥的所有的元素.赋值 checked=false; 然后单独赋值 checked=true* */var mutexbox ...