React JSX


# React JSX

# JSX 简介

JSX 的全称是 JavaScript XML,它是 React 定义的一种类似于 XML 的 JS 扩展语法。

JS + XML 本质是 React.createElement(component, props, ...children) 方法的语法糖。

JSX 作用:用来简化创建虚拟 DOM:

  • 写法:var ele = <h1>Hello,React</h1>
  • 注意 1:它不是字符串, 也不是 HTML/XML 标签
  • 注意 2:它最终产生的就是一个 JavaScript 对象

我们不需要一定使用 JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

# JSX 语法规则

JSX 可以总结出下列语法规则。

# 创建虚拟 DOM 时,不要写引号

创建虚拟 DOM 时,不要写引号。



 




<script type="text/babel" >
  // 1. 创建虚拟 DOM
  const VDOM = <h1>Hello,React</h1>
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6

# 标签中混入 JS 表达式的写法

标签中要混入 JS 表达式,要用花括号 {}





 




<script type="text/babel" >
  const data = 'Hello,React'

  // 1. 创建虚拟 DOM
  const VDOM = <h1>{data}</h1>
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8

注意这里的花括号不是对象的意思,仅是分隔符。

# 标签中类名的写法

标签中样式的类名要用 className 指定而不是 class





 




<script type="text/babel" >
  const data = 'Hello,React'

  // 1. 创建虚拟 DOM
  const VDOM = <h1 className="title">{data}</h1>
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8

如果跟平时写 HTML 一样用 class,会报错:Warning: Invalid DOM property 'class'. Did you mean 'className'?

# 标签中内联样式的写法

标签中的内联样式要用双花括号 {{}} 包裹,并注意属性名转为小驼峰font-size => fontSize)。

本质上,外层花括号表示它里面是 JS 表达式,内层花括号表示一个对象(因为 style 属性本身就是一个 {key: value} 组合),所以内层花括号里的属性值 value 需要转为字符串形式,否则它将作为 JS 变量去读取。





 




<script type="text/babel" >
  const data = 'Hello,React'

  // 1. 创建虚拟 DOM
  const VDOM = <h1 style={{color:'white',fontSize:'60px'}}>{data}</h1>
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8

如果跟平时 HTML 中的一样写 style="color:white;",会报错:Uncaught Invariant Violation: The 'style' prop expects a mapping from style properties to values, not a string.

# 多级结构使用小括号包裹

使用小括号 () 包裹后,代表一个整体,并且可以缩进结构,让代码像 HTML 模板一样美观可读。



 
 
 
 
 




<script type="text/babel" >
  // 1. 创建虚拟 DOM
  const VDOM = (
    <div>
      <h1>Hello,React</h1>
    </div>
  )
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8
9
10

# 只能有一个根标签

只能有一个根标签,如果有多级并列结构,需要用一对 div 标签包裹。




 
 
 
 





<script type="text/babel" >
  // 1. 创建虚拟 DOM
  const VDOM = (
    <div>
      <h1>Hello,React</h1>
      <h2>2021-08-08</h2>
    </div>
  )
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8
9
10
11

如果不用 div 标签包裹,会报错:Uncaught SyntaxError: Inline Babel script: Adjacent JSX elements must be wrapped in an enclosing tag(Babel 编译错误)

# 标签必须闭合

标签必须闭合,可以是自闭合(没有标签体内容的标签),也可以是一对开始标签和结束标签。

# 关于标签首字母

  • 如果首字母小写,那么 React 就会去寻找与之同名的 HTML 标签:
    • 找到,直接转为 HTML 同名元素
    • 未找到,报错(Warning: The tag xxx is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
  • 如果首字母大写,那么 React 就会去寻找与之同名的组件
    • 找到,就会用该组件
    • 未找到,报错(Uncaught ReferenceError: xxx is not defined

因为在 HTML 的标签中,除了文档声明(<!DOCTYPE html>)其它都是小写,所以在 JSX 的逻辑中,一旦标签首字母大写,就不去 HTML 中找有没有同名标签了,而是直接找同名组件,没找到就报错了。

# 注释需要写在花括号中

本质是通过花括号 {} 包裹后,将那行标签变成了 JS 表达式,然后就可以采用 JS 的多行注释语法。

<script type="text/babel" >
  // 1. 创建虚拟 DOM
  const VDOM = (
    <div>
      <h1>Hello,React</h1>
      {/* <p>这是一行注释</p> */}
    </div>
  )
  // 2. 渲染虚拟 DOM 到页面
  ReactDOM.render(VDOM, document.getElementById('example'))
</script>
1
2
3
4
5
6
7
8
9
10
11

(完)