什么是JSX?
一、基本概念及用法:
JSX(JavaScript XML)是一种语法扩展,常用于 React 以描述用户界面(UI)。它看起来很像 HTML,但实际上它是 JavaScript 的一种语法糖,允许开发者在 JavaScript 代码中编写类似 HTML 的语法。
书写形式:
- HTML上凿洞,动态数据露脸
在用React写界面的时候,先写一段HTML作为页面的静态结构,再用大括号标记,加入动态的、可交互的元素,这就像在墙上凿个洞,让动态数据从墙后漏出了脸
{}就像一个洞
React=JS中混写HTML
基本用法:
import React from 'react';
const Greeting = ({ name }) => {
return (
<div>
<h1>Hello, {name}!</h1>
<p>Welcome to our website.</p>
</div>
);
};
export default Greeting;
JSX 的优势
- 可读性: JSX 使得组件的结构更加直观,易于理解和维护。
- 强大的功能: 结合 JavaScript 可以实现动态和复杂的用户界面。
- 编译为 JavaScript: JSX 代码在构建过程中会被转换为 React.createElement 调用,从而生成虚拟 DOM。
注意事项
- 必须有一个父元素: 在 JSX 中,返回的元素必须被一个单一的父元素包裹。
- 使用 Babel 转换: 在实际应用中,JSX 代码通常需要使用 Babel 进行转换,以便浏览器能够理解。
二、深入理解JSX语法
1.JSX是伪装成HTML的JavaScript代码
function App() {
return <div>111</div>
}
这个组件是一个JavaScript函数,并返回了一个值(return后面的部分)
混写在React代码里的标签也不是真正的HTML,而是一种特殊的标签,大名叫做JSX,这里JS指的是JavaScript, X 有扩展(extension)的意思,也表示它与另外一种标记语言XML其实更接近
JSX只是伪装成HTML标签,其实质是JavaScript代码,在发送到浏览器执行之前,React开发工具将JSX标签自动转换为相应的JavaScript代码:
<div>111</div>
与下面的代码是等效的:
_jsx("div",{ children: "111"})
这里的_jsx是开发工具自动导入的一个函数:
import { jsx as _jsx } from "react/jsx-runtime"
所以组件也可以写成:
import { jsx as _jsx } from "react/jsx-runtime"
function App {
return _jsx("div",{ children: "111"})
}
带className的转换:
<div className="mr-wall"></div>
_jsx("div",{ className: "mr-wall"})
嵌套标签:
<div>
<button />
</div>
_jsx("div",{ children: _jsx("button")})
children是一个特殊的属性,包含了嵌套在div里的标签,或者说是div的"孩子" 而button同时也是一个jsx标签,所以children的值是再一次调用_jsx的结果,而不是一个简单的字符串
<div>11{alan}22</div>
转换为:
_jsx("div", {children:["11",alan,"22"]})
当有花括号的时候,标签内容被拆分为多个"孩子",并包括在一个数组内.因为alan不是字符串,而是定义在目前作用范围内的一个变量,所以在转换后的代码里没有加引号,而是直接引用了alan
示例:
<div className = "container">
<div className="mr-wall">11{alan}22</div>
<button />
</div>
转换成JavaScript:
_jsx("div",{
className: "container",
children:[
_jsx("div", { className: "mr-wall", children: ["11",alan,"22"]}),
_jsx("button"),
],
});
2.JSX的返回值:
function App(){
const result = _jsx("input", {});
console.log(result); // 打印到控制台
return result;
}
控制台结果:
Object {type: "input", key:null, ref:null, props:Object, _owner:null}
_jsx函数创建并返回了一个简单的JavaScript对象,跟DOM元素没有什么关系,这个对象的正式名称是React元素(React element),其作用只是描述我们期望在浏览器中看到的结果
3.JSX是一个表达式:
JSX标签赋值给变量或者将其作为参数在调用函数的时候传过去,或者打印在控制台上
let content = <div>咔嚓</div>
showAlert(<input />)
console.log(<div>111</div>)
JSX标签是函数调用( _jsx(...) ),既然是函数调用,JSX标签就是一个JavaScript表达式,可以卸载任何能容纳表达式的地方
_jsx创建的只是一个简单的对象,并不是DOM节点,所以它没有办法appendChild方法供我们使用
4.理解JSX和HTML的区别
// JSX
<input style = {{ minWidth: 200}} />
// HTML
<input style = "min-width: 200px" />
为什么这里有两层大括号,为什么不是单层大括号? 为什么不是引号?
- 第一层括号其实就是墙上那个"洞"
- 第二层括号是JavaScript对象的界定符
所以,这里的sytle属性的值是一个对象,这也解释了为什么括号内是{ minWidth:200 },而不是{ minWidth:200px } 或者 { min-width: 200px },因为后面两个都不是对象的正确写法
第一层是告知这个地方要动态填参数,第二层是传递一个对象,给这个style属性传递一个对象
基于同样的原因,当CSS属性值不是数字时,我们需要使用引号,比如,设置背景颜色时用
<div style = {{ background: "red" }}>
而不是:
<div style = {{ background:red}}></div>
当然,上述是标准的React支持的方法,有一些第三方库(如 styled-components,emotion)可以让我们在JavaScript代码里加入真正的CSS代码,其格式完全原汁原味.我们甚至可以直接从网上复制一段CSS代码放到程序里,不过这些库的实现仍基于上述的标准方法
JSX和HTML的区别
这一表格总结了 JSX 和 HTML 在多个方面的主要区别。JSX 是一种 JavaScript 语法扩展,专为 React 设计,具有更强的表达能力和灵活性,而 HTML 是标准的网页标记语言。
特性 | JSX | HTML |
闭合要求 | 所有标签必须闭合,包括单标签 (如 <img />) | 单标签可以不闭合 (如 <img> ) |
属性命名标准 | 使用小驼峰命名法(如className、onClick)。 | 使用小写字母和短横线(如 class、onclick) |
自定义标签 | 支持自定义标签(如<MyComponent /> ) | 只允许使用标准 HTML 标签 |
模板支持 | 支持内联表达式(如 {expression}) | 不支持内联表达式,只能静态内容 |
引用 CSS 类 | 使用 className 属性来引用 CSS 类 | 使用 class 属性来引用 CSS 类。 |
内嵌样式 | 使用对象语法,例如 style={{ color: 'red' }} | 使用字符串语法,例如 style="color: red;" |
textarea | 直接使用,内容必须用{value} 来控制 | 直接使用,内容为标签之间的文本。 |
label | 需要使用 htmlFor 属性 <label htmlFor = "input-id"> | 使用 for 属性 <label for = "input-id"> |
select | 直接使用,支持 React 的受控组件 使用select标签的value属性标识当前选项,如: <select value = "打">...</select> | 直接使用,不支持受控组件的概念 使用option标签的selected属性标识当前选项,如: <option selected>打</option> |
总结:
JSX就是JavaScript代码,要遵循JavaScript代码规则,当然,我们还可以把JSX看成增强型的HTML,因为它可以支持自定义标签等高级功能