React-JSX

68 阅读4分钟

认识JSX

const element = <h1>Hello, world!</h1>;
ReactDOM.render(element,document.getElementById('id'))

这段element变量的声明右侧赋值的标签语法是什么呢?

  • 它不是一段字符串(因为没有使用引号包裹),它看起来是一段HTML原生,但是我们能在js中直接给一个变量赋值html吗?
  • 其实是不可以的,如果我们讲 type="text/babel" 去除掉,那么就会出现语法错误; 它到底是什么呢?其实它是一段jsx的语法;

JSX是什么?

  • JSX是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法;

  • 它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;

  • 它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);

为什么React选择了JSX

React认为渲染逻辑本质上与其他UI逻辑存在内在耦合

  • 比如UI需要绑定事件(button、a原生等等);
  • 比如UI中需要展示数据状态,在某些状态发生改变时,又需要改变UI; 

他们之间是密不可分,所以React没有讲标记分离到不同的文件中,而是将它们组合到了一起,这个地方就是组件(Component);

  • 当然,后面我们还是会继续学习更多组件相关的东西;  在这里,我们只需要知道,JSX其实是嵌入到JavaScript中的一种结构语法;
  • JSX的书写规范: 
    • JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个div原生(或者使用后面我们学习的Fragment);
    • 为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写;
    • JSX中的标签可以是单标签,也可以是双标签;
    • 注意:如果是单标签,必须以/>结尾;

JSX的使用:

JSX嵌入变量

  • 情况一:当变量是Number、String、Array类型时,可以直接显示
  • 情况二:当变量是null、undefined、Boolean类型时,内容为空; 
    • 如果希望可以显示null、undefined、Boolean,那么需要转成字符串;

    • 转换的方式有很多,比如toString方法、和空字符串拼接,String(变量)等方式;

  • 情况三:对象类型不能作为子元素(not valid as a React child)

JSX嵌入表达式

  • 运算表达式 
  • 三元运算符 
  • 执行一个函数 jsx绑定属性
  • 比如元素都会有title属性
  • 比如img元素会有src属性
  • 比如a元素会有href属性
  • 比如元素可能需要绑定class
  • 比如原生使用内联样式style

JSX 特定属性

你可以通过使用引号,来将属性值指定为字符串字面量

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

也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:

const element = <img src={user.avatarUrl}></img>;

在属性中嵌入 JavaScript 表达式时,不要在大括号外面加上引号。你应该仅使用引号(对于字符串值)或大括号(对于表达式)中的一个,对于同一属性不能同时使用这两种符号。

⚠️: 因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。

例如,JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex

JSX的本质

实际上,jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖。

所有的jsx最终都会被转换成React.createElement的函数调用。

React.createElement在源码的什么位置呢?

  • createElement需要传递三个参数:

  • 参数一:type

    • 当前ReactElement的类型; 
    • 如果是标签元素,那么就使用字符串表示 “div”; 
    • 如果是组件元素,那么就直接使用组件的名称;
  • 参数二:config

    • 所有jsx中的属性都在config中以对象的属性和值的形式存储
  • 参数三:children

    • 存放在标签中的内容,以children数组的方式进行存储; 

    • 当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方

image.png

Babel官网查看

我们知道默认jsx是通过babel帮我们进行语法转换的,所以我们之前写的jsx代码都需要依赖babel。 

可以在babel的官网中快速查看转换的过程babeljs.io/repl/#?pres…