JSX 简易入门

首先,严格定义上来说,JSX 是 react 提供的一种标签式组件声明语法。JSX 只是一种js语言的扩展语法糖,在正式环境运行前,需要经过 babel 工具编译为正式的 JS 代码。

在正式介绍JSX 之前,我们有必要理解,react 框架实现了 virtual dom 功能,开发者可通过react的双向绑定、组件、组件嵌套等工具,将页面的构建逻辑交付于react框架即可,而无需执行实际的 DOM 操作。为了实现 virtual dom ,react 将 DOM 映射为 Component 对象,将 DOM 树映射为组件树。为此,react提供了 createClass 接口用于定于 Component;提供了 createElement 接口用于构建组件树。

基本语法

JSX 高度兼容HTML,即使是react新手也可以迅速写出 JSX 代码:

const element = <div>
  <button>这是一个 button</button>
  <button style={{ width: 100 }}>这是一个包含 style 属性的 button</button>
  <button className="btn btn-default">这是一个带 className 的 button</button>
  <button className="btn btn-default" onClick={() => alert('click me')}>这是一个带事件处理的 button</button>
  <div className="btn-group">
    <button className="btn btn-default">这是被 div 包围的 button</button>
    <button className="btn btn-default">这也是被 div 包围的 button</button>
  </div>
</div>;

这是JSX的基本形式,编译后的代码:

var element = _react2.default.createElement(
  'div',
  null,
  _react2.default.createElement(
    'button',
    null,
    '\u8FD9\u662F\u4E00\u4E2A button'
  ),
  _react2.default.createElement(
    'button',
    { style: { width: 100 } },
    '\u8FD9\u662F\u4E00\u4E2A\u5305\u542B style \u5C5E\u6027\u7684 button'
  ),
  _react2.default.createElement(
    'button',
    { className: 'btn btn-default' },
    '\u8FD9\u662F\u4E00\u4E2A\u5E26 className \u7684 button'
  ),
  _react2.default.createElement(
    'button',
    { className: 'btn btn-default', onClick: function onClick() {
        return alert('click me');
      } },
    '\u8FD9\u662F\u4E00\u4E2A\u5E26\u4E8B\u4EF6\u5904\u7406\u7684 button'
  ),
  _react2.default.createElement(
    'div',
    { className: 'btn-group' },
    _react2.default.createElement(
      'button',
      { className: 'btn btn-default' },
      '\u8FD9\u662F\u88AB div \u5305\u56F4\u7684 button'
    ),
    _react2.default.createElement(
      'button',
      { className: 'btn btn-default' },
      '\u8FD9\u4E5F\u662F\u88AB div \u5305\u56F4\u7684 button'
    )
  )
);

与html主要的不同点为:

  • 不能使用 class 声明元素类,改用 className

  • 绑定事件必须使用 驼峰命名

  • style 属性必须为对象

声明属性

JSX中,父组件可通过属性方式,将配置值传递到子组件中:

const element = <div tabIndex="0" name="someDiv"></div>;

标签属性最终被编译成对象,传递到 createElement 接口,如上述代码编译结果为:

var element = React.createElement("div", { tabIndex: "0", name: "someDiv" });

属性值既接受字符串,也接受js表达式,同样通过 {} 闭合,如:

const areWeRocking = true;
const element = <div areWeRocking={areWeRocking}></div>;

嵌套子组件

JSX 中,标签可以包含子标签,子标签集合会被编译为 children 传递到 createElement 函数,如:

const element = <div>
  <button>这是一个button</button>
</div>;

编译结果:

var element = React.createElement(
  "div",
  null,
  React.createElement(
    "button",
    null
    "\u8FD9\u662F\u4E00\u4E2Abutton"
  )
);

嵌套js逻辑

JSX 支持嵌套 js表达式,方式非常简单,使用 {} 包含表达式即可,这使得我们可以轻易地在JSX实现各种逻辑

  • 循环

const array = [1, 2, 3, 4];
const element = <div>{array.map(item => <span>{item}</span>)}</div>;
  • 分支

const areWeRocking = true;
const element = <div>{areWeRocking ? 'awesome' : 'holy shit'}</div>;
  • 函数

const giveMeYourName = () => <strong>tecfan</strong>;
const element = <div>{giveMeYourName()}</div>;

JSX 表达能力非常强,一是可以无限制的嵌套组件标签、js代码,实现复杂逻辑;二是支持函数表达式,通过函数我们可以实现任意功能。

JSX 树编译逻辑

JSX 语法并不晦涩,只有三条简简单单的规则:

  • 通过 XML 形式声明

  • 标签允许声明任意属性

  • 标签内可以嵌套子标签,也可以嵌套js表达式

编译器而言的处理逻辑也会变的很简单:

  1. 解析标签名(tagName)

  2. 解析标签属性,拼合为属性对象(props)

  3. 遍历内容集合(children)

    1. 如果内容为JS表达式,执行表达式,并将结果存入 children 变量

    2. 如果内容为标签,执行第一步,并将结果存入 children 变量

上面过程中生成的变量 tagNaem、props、children 被传递到 createElement 接口:

React.createElement(
  tagName,
  props,
  ...children
)

后记

在web领域我们见过太多模板,angular、vue、lodash、swig...各种模板都构造了其独特的语法、控制结构,许多甚至已经大幅度偏离html语法基础。

JSX 则成功的另辟小径,只提供基于html的语法糖,只要熟悉html、js,入门难度非常低。良好的程序结构,应该是简单纯粹,而又不失表达能力的,JSX正符合这种良好设计。


1 篇内容引用
1.4k 声望
6.8k 粉丝
0 条评论
推荐阅读
🦀🦀🦀 一个普通人的前端职业成长之路
大家好,我是 范文杰,一个前端从业者,最近刚写完我的第一本小册《Webpack 核心原理与实践应用》,这对我是一个不小的职业突破,所以不能免俗地想做个总结,分享我这九年工作的成长经历,以及我对前端这个职业的...

范文杰3阅读 1.1k

封面图
深入理解React Diff算法
fiber上的updateQueue经过React的一番计算之后,这个fiber已经有了新的状态,也就是state,对于类组件来说,state是在render函数里被使用的,既然已经得到了新的state,那么当务之急是执行一次render,得到持有新...

nero31阅读 11.8k评论 3

把React新文档投喂给 GPT-4 后...
大家好,我卡颂。最近,React新文档终于上线了。从内容上看,新文档包括:理论知识、学习指引API介绍从形式上看,新文档除了传统的文字内容,还包括:在线Demo示意图小测验可以说是阅读体验拉满。但是,由于文档...

卡颂7阅读 6.1k评论 3

封面图
PDF 预览和下载你是怎么实现的?
在开发过程中要求对 PDF 类型的发票提供 预览 和 下载 功能,PDF 类型文件的来源又包括 H5 移动端 和 PC 端,而针对这两个不同端的处理会有些许不同,下文会有所提及。

熊的猫7阅读 1.7k评论 1

封面图
第九期:前端九条启发分享
下图是一个常见的列表, 点击列表里的详情按钮会跳到详情页, 那么也许我们在详情页修改了数据状态, 此时可能需要把修改后的状态直接传给列表页从而本地直接更新列表, 这样就不用发送新的api请求与后端交互了。

lulu_up8阅读 462

React为什么不将Vite作为默认推荐?
CRA推出于2016年,彼时还没有成体系的React脚手架工具供大家使用,再加上这是官方工具,一经推出就受到了欢迎。截止当前,CRA仓库已经收获快10wstar。

卡颂4阅读 1.2k

封面图
如何优雅的实现网页多主题风格换肤功能?
对于网页换肤,例如最常见的深色、浅色风格已经是很常见的一个需求了。一直以来也有很多的实现方案,这里我主要介绍一下基于 CSS variable的实现方式

前端有猫腻4阅读 1.3k评论 1

封面图
1.4k 声望
6.8k 粉丝
宣传栏