🌙 认识JSX
JSX = JS + XML:JSX就是Javascript和XML结合的一种格式。React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM,当遇到<,JSX就当作HTML解析,遇到{就当JavaScript解析.
const div = (<div> React JXS <div>);
const dom = (
<div>
<h1>Hello World!</h1>
<h2>Now Time {new Date().toLocaleTimeString()}.</h2>
</div>
);
2
3
4
5
6
7
🌙 JSX特点
- 通过编译成普通JS运行在JS环境中。
- 使用XML标签式语法定义JS变量的值。
- 在标签内使用
{}包裹,写JS表达式。
import React from 'react'
const Component = React.Component
class App extends Component{
render(){
return ( {/*必须使用()包裹*/}
{/*在<>中写HTML*/}
<ul className="my-list">
{/*在{}中写JS代码*/}
<li>{false?'hello':'hi'}</li>
<li>I love React</li>
</ul>
)
}
}
export default App;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
🌙 JSX {JS表达式}
JSX中{}内部的JS表达式:
| JS表达式类型 | JSX代码块 | 测试结果 |
|---|---|---|
| string/number | <div> {'hello'}{111} <div> | hello 111 |
| array | <div>{[1,2,3]}</div> | 123 |
| true/false | <div>{true}{false}</div> | 不显示 |
| object | object = {width:"20px"} <div style={object}> | |
| =、+、-、*、/ | <div>{a=1}{a=a+2}{a=a-1}{a=a*6}{a/2}<div> | 132126 |
| ?a:b | <p>{a=0}{a>1?'haha':'hehe'}</p> | 0hehe |
| function | <p>{alert(111)}</p> | 弹出框 |
- 允许:
number、string、Array、React元素,其中Array会被扁平化,数组的每一项都将作为子节点渲染 - 不允许:普通的
JavaScript对象、function函数 - 无渲染:
null、undefined、boolean、symbol
🌙 JSX注意事项
🌙 JSX创建DOM规范
首字母小写的字符串是HTML标签
ReactDOM.render( <div className="foo" />, document.getElementById("app") );1
2
3
4首字母大写的变量是React组件
function MyComponent() {
return (
<div>
<h1>我的组件</h1>
<p>一个无属性、无状态、最简单的组件</p>
</div>
);
}
// 渲染一个 MyComponent 组件到页面的 "#app" 容器中
ReactDOM.render(
<MyComponent />,
document.getElementById("app")
);
2
3
4
5
6
7
8
9
10
11
12
13
14
🌙 JSX声明React元素规范
必须有且只有一个React元素根节点
// 反例 const ele1 = ( <h1>没有一个根标签包裹</h1> <p>与 h1 标签同级</p> ); // 正确 const ele2 = ( <div> <h1>没有一个根标签包裹</h1> <p>与 h1 标签同级</p> </div> );1
2
3
4
5
6
7
8
9
10
11
12作
Flex布局的时候,外层不能有包裹元素 , 在React16 之后,我们可以使用<Fragment>标签替代,在渲染时就没有最外层的包裹标签:import React,{Component,Fragment } from 'react' class Test extends Component{ render(){ return ( <Fragment> <h1>Fragment标签</h1> <p>使用Fragment来代替根节点,去除最外层包裹,便于flex布局</p> </Fragment> ) } }1
2
3
4
5
6
7
8
9
10
11JSX中所有的标签都必须正确闭合
// 反例 const ele = <input type="text">; // 正确 const ele = <input type="text"/>; const ele = <div />1
2
3
4
5标签嵌套规则需要符合 W3C 标准,否则会给出相应警告
低级标题里不允许嵌套高级标题
在 p 标签里不允许嵌套块级元素
// 反例 ReactDOM.render( <div> <h2> <h1>h1 的级别比 h2 高</h1> </h2> <p> <div>在 p 标签里嵌套了块级元素</div> </p> </div>, document.getElementById("app") );1
2
3
4
5
6
7
8
9
10
11
12
13
🌙 JSX标签属性规范
- 所有的属性都是小驼峰命名的
class属性 改为classNamefor属性 改为htmlForcolspan属性 改为colSpan- **在表单元素上:**存在
value与defaultValue、checked与defaultChecked,它们有不同的意义
// import classes form './myCss.css'
{/*JSX 中的注释方式*/}
{/*style属性必须使用 {{}} */}
<div style={{width: "20px", height: "30px"}}>
{ props.text }
</div>
{/*html class属性*/}
<div className="myClass"></div>
{/*html input标签, JSX中所有的标签都必须有闭标签*/}
<input type="text" />
{/*html label标签 */}
<label htmlFor="name" class="mayName"></label>
{/*调用.css 文件中的css属性, mycss 为css文件中的类*/}
<div className={classes['mycss']}></div>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意:当 JSX 代码出现换行时,建议使用一对小括号 () 将代码包裹起来,可以防止分号自动插入的 Bug
const ele = (
<div>
使用 () 包裹了 div 标签
</div>
);
2
3
4
5
注意:使用 {} 计算属性值时,会对表达式的返回值调用 toString 方法再赋值。
🌙 JSX本质
本质上,JSX是React.createElement的语法糖,是申明react元素的更高效的方式,不仅允许在JS中编写DOM结构,还可以在DOM节点中插入js表达式,从而更简单、更快速的实现数据绑定。
JSX 的本质 API:React.createElement
/**
* JSX本质API:
* 创建 React 元素
* @param component:组件名,字符串表示的HTML元素或变量名表示的 React.Component 子类
* @param props:组件的属性对象
* @param children:组件的子节点
* */
React.createElement(component, props, ...children);
2
3
4
5
6
7
8
🌙 JSX的优势
使用有好的HTML式标签方式创建React元素,更加简单快捷,结构清晰,代码可读性强
JSX被编译时进行了优化,执行速度更快
JSX是类型安全的,在编译过程中就能发现错误
JSX在不同的平台提供不同的编译器,可以跨平台(React Native)
🌙 编译器
jsx 通过编译器转为浏览器可以认识(js 引擎)的js代码,使用 babel (opens new window): @babel/preset-react 和 plugin-transform-react-jsx来完成编译转换。
const App = () => <div>hello world</div>
通过上述编译器编译为:
import { jsx as _jsx } from "react/jsx-runtime";
const App = () => /*#__PURE__*/_jsx("div", {
children: "hello world"
});
2
3
4
在 React 运行时,处理为 ReactElement (opens new window), 也就是 虚拟DOM:
function ReactElement(
type,
key,
self,
source,
owner,
props,
debugStack,
debugTask,
) {
// ...简化代码
const element = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type,
key,
ref,
props,
};
return element
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24