- 原文地址:Alternatives to JSX
- 原文做者:Seva Zaikov
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:EmilyQiRabbit
- 校对者:xionglong58,sunui
现在,JSX 已是一个很是受欢迎的框架模版了,它的应用也不只仅局限于 React(或其余 JSX 衍生模版)。可是,若是你并不喜欢它,或者有某些想要避免使用它的项目,或者只是好奇不使用 JSX 该如何书写 React 代码的时候,该怎么办呢?最简单的方法就是去阅读官方文档,可是,官方文档很简短,而在本篇文章中咱们为您提供了更多的选择。html
免责声明:我的来讲,我很喜欢 JSX,在我全部的 React 项目中我都使用了它。可是,我对本文主题从新进行了调研,而且但愿和你分享个人所见。前端
首先,咱们须要明白什么是 JSX,这样咱们才能在纯 JavaScript 中编写对应的代码。JSX 是一种特定域编程语言,意味着咱们须要将 JSX 代码转码,以便获得常规的 JavaScript,不然浏览器将没法解析代码。展望前景光明的将来,若是你想要使用 modules,而且全部须要的功能都能被目标浏览器支持,你仍然不能彻底丢弃转码这一步,这多是一个问题。node
也许理解 JSX 将会被解析成什么最好的方法就是使用 babel repl 实际操做一次。你须要点击左侧面板的 presets
而且选择 react
,这样解析器才能正确的解析代码。这以后,你就能在右侧实时看到编译生成的 JavaScript 代码。例如,你能够尝试下这段代码:react
class A extends React.Component {
render() {
return (
<div className={"class"} onclick={some}>
{"something"}
<div>something else</div>
</div>
)
}
}
复制代码
个人运行结果以下:android
class A extends React.Component {
render() {
return React.createElement("div", {
className: "class",
onclick: some
}, "something", React.createElement("div", null, "something else"));
}
}
复制代码
能够看到,每一个 <%tag%>
结构都被替换成了函数 React.createElement。第一个参数是 react 组件或者内建标签名字符串(好比 div
或 span
),第二个参数则是组件属性,其余的参数则都被视做组件的子元素。ios
我强烈推荐你使用不一样结构的组件树反复尝试,来观察 React 如何渲染值为 true
、false
、数组、或者组件等的属性:即便你只尝试使用 JSX 和一些其余内容的代码,它也颇有帮助。git
若是你想深刻学习 JSX,能够参考官方文档github
因为编译结果是固定的,咱们其实也能够将全部的 React 代码直接以这种形式写出,可是其实这种方式存在一些问题。web
第一个问题就是很是繁琐。真的至关繁琐,而罪魁祸首就是 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")
);
}
}
复制代码
若是 React.createElement
或者 h
你都已经尝试过了,你就能够看出它们都存在一些缺点。首先,函数须要三个参数,因此在没有属性的状况下,你仍是必须传递 null
做为参数,同时,className
做为一个很经常使用的属性,在每次使用的时候都须要新建一个对象。
做为一个替代方案,你可使用 react-hyperscript 库。它不须要你提供空属性,而且容许你用点号的方式定义 class 和 id(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")
]);
}
}
复制代码
若是你并不反感 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,这个工具就很方便。
它的核心思想和 hyperscript 很相似,但它采用了一个很优雅的方式,值得一看。现现在,有不少相似的帮助库,因此到底选择哪一个也因人而异;而它们都有可能能给你的项目带来些灵感。
ijk 这个库的思路是只用数组来写模版,并将位置做为参数。这样写的优点在于你不须要老是写 h
(是的,有时候总写 h
也会让人以为很冗余!)。以下是一个使用案例:
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,也不是说 JSX 有什么很差。可是你可能会好奇若是不用它,你要怎么写代码,还有你的代码可能会是什么样子,本文的目的就只是回答了这个问题。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。