JSX
简介
在代码中同时包含 JS 和 HTML 标记,这种写法就是 React 的「模版语言」JSX。
JSX 并不是一个新的模版语言,而是一个语法糖,可以用 JS 的方式来实现。使用 React.createElement() 这个 API 来创建一个组件的实例。
例如:
import { useState } from 'react';
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>add</button>
</div>
);
};
export default App;
调用 createElement 创建一个 React 元素,具有 type
、 props
和 children
。
import { createElement, useState } from 'react';
const App = () => {
const [count, setCount] = useState(0);
return createElement(
'div',
null,
createElement('h1', null, count),
createElement(
'button',
{
onClick: function () {
return setCount(count + 1);
}
},
'add'
)
);
};
export default App;
在实际开发中,不推荐使用 React.createElement()
这种方式,在官方中也将其列入「旧版 API」中,使用 JSX 更简洁易读。
JSX 规则
- 返回单个根元素
- 所有标签要闭合
- 采用驼峰命名
将 HTML 转换为 JSX 的转换器:https://transform.tools/html-to-jsx
原理
浏览器无法直接理解 JSX,需要通过 Babel 和 TypeScript 转换为 JS。
Babel 编译,@babel/plugin-transform-react-jsx
老版本的 React 中,为什么写 jsx 的文件要默认引入 React?
import React from 'react';
function App() {
return <div>hello,world</div>;
}
因为 JSX 被 Babel 编译后,会变成 React.createElement()
形式,所以需要引入 React,防止找不到 React 引起报错。
为何要返回单个根元素?
在 React 中,组件的返回值必须是一个根元素。如下所示都是错误的:
function Foo() {
return (
<div>1</div>
<div>2</div>
)
}
function Bar() {
return (
<div>
{isOpen && (
<div>1</div>
<div>2</div>
)}
</div>
)
}
前面说了,JSX 是 React.createElement()
的语法糖。Babel 会将 Foo 组件转换为下面这样:
function Foo() {
return React.createElement('div', null, '1')
React.createElement('div', null, '2');
}
这里试图返回两个东西,这不符合 JS 语法。
注释
在 JSX 中写注释不能单独使用//
,需要这么写 {/* 注释 */}
htmlFor
label
标签不能使用for
,要用htmlFor
<label htmlFor="zgh"></label>
className
为了防止和 js 中的class
类名冲突,需要将class
写成className
,小驼峰命名
<input className="input" />
循环遍历
JSX 中默认对数组进行 join()
操作,如下代码会在页面上显示“abc”
function List() {
const arr = ['a', 'b', 'c'];
return <div>{arr}</div>;
}
利用原生 js 写法,使用 map
遍历数组,因为 map 有返回值,不能使用 forEach