2025-12-15 日报 Day303

Yuyang 前端小白🥬

今日的鸡汤

js和jsx

JSX 是一种 JavaScript 的语法扩展(syntax extension),允许开发者在 JavaScript 代码中以类似 HTML 的声明式方式描述 UI 结构。

但是浏览器不支持运行JSX代码,因此需要通过编译工具(通常是 Babel)将 JSX 转换为标准的 JavaScript 代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react';

const App = () => {
return <h1>test babel</h1>
}


automatic会转换为==============>
import React from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
const App = () => {
return /*#__PURE__*/_jsx("h1", {
children: "test babel"
});
};

classic会转换为=============>
import React from 'react';
const App = () => {
return /*#__PURE__*/React.createElement("h1", null, "test babel");
};

Reaect.createElement 是 React 提供的一个用于创建 React 元素的函数。它接受三个参数:

  1. type:元素的类型,可以是字符串(表示 HTML 元素)或 React
  2. config: 当前元素的属性 如{ id: ‘test’}
  3. children: 当前元素的子节点,可以是字符串、数字、React 元素或数组等

且从React18之后 在JSX中不需要引入React

Refer:git@github.com :ZacharyL2/mini-react.git

从代码来看其实就创建虚拟DOM,然后render

JSX创建Element

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
interface VirtualElement {
type: string | Function;
props: {
[key: string]: any;
children: VirtualElement[];
};
}

const createTextElement = (text: string): VirtualElement => ({
type: "TEXT",
props: {
nodeValue: text,
children: []
}
})

const isVirtaulElement = (element: unknown): element is VirtualElement => {
return typeof element === 'object' && element !== null && 'type' in element && 'props' in element;
}
const createElement = (
type: VirtualElement,
props: Record<string, unknown> = {},
...child: (unknown | VirtualElement)[]
) => {
const children = child.map(c => isVirtaulElement(c) ? c : createTextElement(String(c)));
return {
type,
props: {
...props,
children
}
}
}

Render:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const updateDom = (DOM, prevProps, nextProps) => {
const defaultPropKeys = 'children';

for(const [removePropKey, removePropValue] of Object.entries(prevProps)){
if(removePropKey.startsWith('on')){
const eventType = removePropKey.slice(2).toLowerCase();
DOM.removeEventListener(eventType, removePropValue);
} else if(!(removePropKey in nextProps) && !defaultPropKeys.includes(removePropKey)){
DOM[removePropKey] = '';
}
}

for(const [addPropKey, addPropValue] of Object.entries(nextProps)){
if(addPropKey.startsWith('on')){
const eventType = addPropKey.slice(2).toLowerCase();
DOM.addEventListener(eventType, addPropValue);
} else if(!defaultPropKeys.includes(addPropKey)){
DOM[addPropKey] = addPropValue;
}
}
}


// create dom base on node type
const createDOM = (fiberNode) => {
const {type, props} = fiberNode;
const DOM = null;

if(type === 'TEXT'){
DOM = document.createTextNode('');
}else if(typeof type === 'string'){
DOM = document.createElement(type);
}

if(DOM !== null){
updateDOM(DOM, {}, props);
}
return DOM;
}

const render = (element, container) => {
const DOM = createDOM(element);
if(Array.isArray(element.props.children)){
for(const child of element.props.children){
return (child, DOM);
}
}
container.appendChild(DOM);
}
评论
此页目录
2025-12-15 日报 Day303