React基础——你真的理解JSX嘛

222 阅读4分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

本篇文章为学习笔记,主要讲React基础内容JSX image.png

一、什么是JSX

const element = <h1>Hello, world!</h1>;

1、描述

全称Javascript XML,React定义的一种类似于XML的JS扩展语法

2、作用

用来简化创建虚拟DOM,不是字符串,也不是HTML/XML标签,最终产生的是一个JS对象

在控制台分别输出虚拟DOM真实DOM如下图 image.png 可以看到虚拟DOM是一个ReactElement对象,真实DOM,debugger进去可以看到,节点上有很多属性,如下图,而虚拟DOM属性比较少,虚拟DOM是react内部使用,无需真实DOM那么多属性 image.png

3、本质

React.createElement(component, props, ...children)方法的语法糖 以下代码完全等效

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

const element = React.createElement(
    'h1', 
    {className: "greeting"}, 
    'Hello, world!'
)

所以创建虚拟DOM有两种创建方式

  • JSX,需要babel转换为 React.createElement,如下图
  • React.createElement(纯js),不需要babel转换,类似jquery的写法 image.png

二、React设计JSX的原因

1、为什么不用React.createElement直接写,而用JSX

对于复杂的视图结构,如下图,JSX层次分明,嵌套关系清晰,而React.createElement杂糅在一起,给人混乱的感觉 image.png 因此写JSX可以降低学习成本,提高开发效率 image.png

2、官方文档 React认为渲染逻辑本质上与其他UI逻辑内在耦合,比如,在UI中需要绑定处理事件、在某些时刻状态发生变化时需要通知到UI,以及需要在UI中展示准备好的数据

React并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离

三、如何使用JSX

先来一个示例

const myId = 'idId'
const myData = 'hello! React'
const vDom = (
   <div id='test'>
      <h2 className='title' id={myId.toLowerCase()}>
          <span style={{color: 'white', fontSize: '20px'}}>
            {myData}
          </span>
      </h2>
    
      <h2 className='title' id={myId.toLowerCase()}>
          <span style={{color: 'white', fontSize: '20px'}}>
            {myData}
          </span>
      </h2>
  </div>
),

ReactDOM.render(vDom, document.getElementById('text'))

1、JSX语法

  • 只能有一个根元素
  • 标签需要闭合
  • 为了便于阅读,可以将JSX拆分为多行,跟html写法一样,建议将内容包裹在括号中
  • 标签首字母
    • 如果是小写字母开头,React则将改标签转为html中同名元素,若html没有同名标签,则报错
    • 如果是大写字母开头,React就去渲染对应的组件,若组件没有定义,则报错
  • 样式的类名指定不用class,要用className
    • React用camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定
  • 内敛样式需要写双花括号,且属性名要用小驼峰,而非中划线分割,如style={{color: 'white', fontSize: '20px' }}
  • 标签想要混入JS表达式,要用{}不要写引号
  • {}中不能写JS语句

2、区分JS语句与JS表达式

  • 一个表达式会产生一个值,可以放在任何一个需要值的地方,比如如下值
    • a
    • a+b
    • demo(1)
    • arr.map
    • function test() {}
  • JS语句
    • if(){}
    • for(){}
    • switch(){}

3、扩展,为什么React要用className,而非class?而Vue的JSX用的是class

首先,react是可以直接使用class的,样式也能生效,只不过控制台会提示一个如下warning image.png

其次,React 不使用 class并不是技术问题,而是哲学问题

React的JSX 虽然看着像 HTML,但它本质还是JS。而Vue的JSX看着想React的JSX,但是它更接近于template

image.png

四、JSX的优缺点

1、优点

  • XML对树状结构优秀的表现力
    • 不管是「嵌套」还是「属性」,JSX都能很自然的描述,我们可以很容易从如下JSX结构推导出实际视图效果
  • JS在运行时的灵活
    • JSX作为JS语法糖,可以用JS语法灵活的描述视图状态,相比较,Vue的template就会差一些

2、缺点

  • JSX 表达的是 Virtual DOM 而不是 HTML,所以它不是模板,概念理解上确实有点门槛
  • 原生浏览器不支持,依赖编译,工具链门槛高
    • JSX需要先编译为JS才能在宿主环境执行,经过Transform才能在浏览器中运行,而有了 Babel就要折腾工具链

参考: zhuanlan.zhihu.com/p/374521473