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.

# label 标签 for 属性写法

label 标签中有一个 for 属性,它用于跟指定的 input 标签建立绑定关系(通过设置 for 的值为 input 标签的 id 值)。当点击 label 的时候,会自动获取 input 的焦点,input 会变成输入状态。

但是在 jsx 语法中 for 默认是循环,所以 label 标签的 for 属性需要替换成 htmlFor





 
 






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

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

使用小括号 () 包裹后,代表一个整体,并且可以缩进结构,让代码像 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

(完)