学习点
相关的基本概念如:虚拟 DOM、JSX 等
React 是什么
需求:在页面上显示一个按钮,按钮显示的文字内容为:Hello, Count:0
,每点击一次该按钮,count 的数字加1
JS实现
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#content {
font-size: 22px;
border: 1px solid grey;
cursor: pointer;
padding: 6px 10px;
display: inline-block;
border-radius: 10px;
}
</style>
</head>
<body>
<div id="root">
<div id="content" onclick="changeText()">Click Me, Count: 0</div>
</div>
<script lang="javascript">
let count = 0;
function changeText() {
count++;
document.getElementById("content").innerHTML = `Click Me, Count: ${count}`;
}
</script>
</body>
</html>
React实现
javascript
import { useState } from 'react';
export default function MyApp() {
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
初始准备
初始化一个 React 项目
初始化之后删除掉无用的代码和文件,以便我们可以更好去学习
- index.js
javascript
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<div>Simple React</div>);
- index.html
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Simple React</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
虚拟 DOM
DOM 是 html 的编程接口,通过 DOM 的方式可以操作文档的结构、样式和内容
- DOM 是针对 html、xml 编程接口和编程语言无关
- DOM 实现相当于一个独立的程序,可以用 js、java、python 实现
- 而通过DOM 实现可以获取一个 DOM 对象,从而操作 DOM 对象
javascript
let element = document.getElementById('root')
let obj = {}
for (let key in element){ obj[key] = element[key]}
console.log(obj)
可以通过代码去修改 DOM 对象,但是开销会非常大,所以引入了虚拟 DOM,虚拟 DOM 是用于描述 DOM对象的对象,在 js 中绝大部分的 DOM 对象的都是非必需的
在 react 中直接打印一个react 对象
javascript
console.log(<div>Simple React</div>)
总之,对比来看
- 没有虚拟 DOM 的情况下,直接操作一个 DOM 对象,其发生的变化需要遍历整棵 DOM 树
- 有虚拟 DOM 的情况下,直接操作一个 DOM 对象就是操作其虚拟 DOM,根据前后两个虚拟 DOM 之间的变化,可以计算出页面需要变化的地方
JSX 相关概念
JSX 是 JavaScript 的语法扩展,他既不是 js 也不是 html,通常我们使用 babel 来进行 jsx 的转换
JSX 相关概念
JSX 是 JavaScript 的语法扩展
- 新的转换形式
javascript
import ReactDOM from 'react-dom/client';
const root = ReactDOM.createRoot(document.getElementById('root'));
let element = <div>Hello</div>
root.render(element);
编译后会变成这样的 js 代码,为什么刚刚在 babel 中会有所不同
javascript
let element = /*#__PURE__*/(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", {
children: "Hello"
}, void 0, false, {
fileName: _jsxFileName,
lineNumber: 4,
columnNumber: 15
}, undefined);
babel编译后的,实际上是因为开发环境和生产环境的不同导致的
javascript
import { jsx as _jsx } from "react/jsx-runtime";
const element = /*#__PURE__*/_jsx("div", {
children: "123"
});
不管是哪种方式,它们返回的都是一个虚拟 DOM 对象
- 旧的转换形式,需要导入 React
javascript
import React from 'react';
let element = <div>Hello</div>
React.createElement("div", null, "Hello")
React 和 ReactDOM 的职责划分
- react:组件相关核心 API 的暴露
- react-dom:和 react 配套,将写好的组件进行渲染