1、什么是JSX


在上一个小节中,我们利用React.createElement()方法创建了虚拟DOM。但是这种方法非常的麻烦,如果结构非常复杂的情况下,那么是灾难性的,例如多添加一个span标签,代码如下:

let element = React.createElement('h2', {title: 'hi'}, [
    'hello world',
    React.createElement('span', null, '!!!!!!')
]);

所以才有了JSX语法,即:这个有趣的标签语法既不是字符串也不是 HTML。

它被称为 JSX,是一个 JavaScript 的语法扩展。

例如:

let element = <h2 title="hi">hello world<span>!!!!!!</span></h2>

JSX写起来就方便很多了,在内部会转换成React.createElement(),然后再转换成对应的虚拟DOM,但是JSX语法浏览器不认识,所以需要利用babel插件进行转义处理。

babel的地址:

<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

2、JSX的使用方法


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="../react.development.js"></script>
  <script src="../react-dom.development.js"></script>
  <script src="../babel.min.js"></script>
</head>
<body>
  <div id="app"></div>
  <script type="text/babel">
    let app = document.querySelector('#app');
    let root = ReactDOM.createRoot(app);
    let element = (
      <h2 title="hi">
        hello world
        <span>!!!!!!</span>
      </h2>
    ); 
    root.render(element);
  </script>
</body>
</html>

3、JSX语法详解


JSX 实际上等于 JavaScript + XML 的组合,那么就有很多结构限制,具体如下:

  • 标签要小写

  • 单标签要闭合

  • class属性与for属性

    ​ 为了与html属性区分,需要改成className和htmlFor属性。

  • 多单词属性需驼峰,data-*这种自定义属性不需要

  • 唯一根节点

    ​ 像这样的两个跟节点不行:

    let app = document.querySelector('#app');
    let root = ReactDOM.createRoot(app); 
    let element = (
      <h2 title="hi" className="box">
        hello world
        <span>!!!!!!</span>
        <label htmlFor="elemInput">用户名:</label>
        <input id="elemInput" type="text" tabIndex="3" data-userid="123" />
      </h2>
      <p>ppppppp</p>
    ); 
    root.render(element);
    

​ 可以使用<React.Fragment>作为根节点,它不会渲染到页面中。

正确的写法:

let app = document.querySelector('#app');
let root = ReactDOM.createRoot(app); 
let element = (
    <React.Fragment>
        <h2 title="hi" className="box">
            hello world
            <span>!!!!!!</span>
            <label htmlFor="elemInput">用户名</label>
            <input id="elemInput" type="text" tabIndex="3" data-userid="123" />
        </h2>
        <p>ppppppp</p>
    </React.Fragment>
); 
root.render(element);
  • { } 模板语法

    ​ 使用{}包裹之后,可以在其中使用js语法。

  • 添加注释

    ​ 使用{}包裹之后,可以在其中使用js的注释。

  • 属性渲染变量

    ​ 在{}中可以添加变量,变量的值才是属性的值。

  • 事件渲染函数

    ​ 在{}中可以添加函数,比如点击事件的函数。

  • style渲染对象

    ​ 在style后面的{}中可以添加一个对象,它的属性和值会成为style的属性和值。

  • { } 渲染 JSX

    ​ 在{}中可以写JSX语法,也就是嵌套另一个JSX,如此循环嵌套都可以。

let app = document.querySelector('#app');
let root = ReactDOM.createRoot(app); 
let myClass = 'box';
let handleClick = () => {
    console.log(123);
}
let myStyle = {
    color: 'red'
};
let element = (
    <div>
        { /* <p>{ 1 + 1 }</p> */ }
        <p className={myClass}>{ 'hello' }</p>
        <p onClick={handleClick}>{ 'hello'.repeat(3) }</p>
        <p style={myStyle}>{ true ? 123 : 456 }</p>
        <p>{ <span>span111</span> }</p>
        <p><span>span222</span></p>
    </div>
); 
root.render(element);

这里可以看到react中的模板语法采用的是单大括号,这一点跟Vue不太一样,Vue采用的是双大括号。

在React模板中,可以直接渲染JSX进去,是非常强大的,后面也会经常利用这一点特性去进行操作。