2025-05-01 日报 Day173

2025-05-01 日报 Day173

Yuyang 前端小白🥬

今日的鸡汤

真正的勤勉,从来不是盲目地忙,而是时时有所创造、事事有所成就、处处有所精进。

今日学习内容

1、https://pomb.us/build-your-own-react/

今日笔记

1、Step zero: Review

1
2
3
const element = <h1 title="foo">hello</h1>
const container = document.getELementById("root")
ReactDOM.render(element,container)

JSX -> Babel(replace the code inside the tags with a call to createElement, passing the tag name, the props and the children as parameters.) -> ReactDOM.render -> DOM

1
2
3
4
5
const element = React.createElement(
"h1",
{ title: "foo" },
"Hello"
)
1
2
const node = document.createElement(element.type)
node["title"] = element.props.title

2、Step 1: The createElement Function

1
2
3
4
5
6
7
8
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)
const container = document.getElementById("root")
ReactDOM.render(element,container)

Let’s see the createELement calls.

1
2
3
4
5
6
const element = React.createElement(
"div",
{ id: "foo" },
React.createElement("a", null, "bar"),
React.createELement("b")
)
1
2
3
4
5
6
7
8
9
10
11
12
13
function createELement(type, props, ...children){
return {
type,
props:{
...props,
children: children.map(child => {
typeof child === "object"
? child
: createTextElement(child);
}),
}
}
}

The children array could also contain primitive values like strings or numbers. So we’ll wrap everything that isn’t an object inside its own element and create a special type for them: TEXT_ELEMENT.

1
2
3
4
5
6
7
8
9
function createTextElement(text){
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: [],
},
}
}

But we still want to use JSX here. How do we tell babel to use Didact’s createElement instead of React’s?
If we have a comment like this one, when babel transpiles the JSX it will use the function we define.

1
2
3
4
5
6
7
/** @jsx Didact.createElement */
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)

3、Step2: The render Function
In this section, we will introduce the render function, which will take the element we created and render it to the DOM.

1
2
3
function render(element, container){
// TODO create dom nodes
}

We start by creating the DOM node using the element type, and then append the new node to the container.

1
2
3
4
5
6
7
8
9
function render(element, container){
// We start by creating the DOM node using the element type, and then append the new node to the container.
const dom = document.createElement(element.type);
// We recursively do the same for each child.
element.props.children.forEach(child => {
render(child, dom);
});
container.appendChild(dom);
}

We also need to handle text elements, if the element type is TEXT_ELEMENT we create a text node instead of a regular node.

1
2
3
4
5
6
7
8
9
10
11
12
13
function render(element,container){
const dom =
element.type === "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(element.type);

// We recursively do the same for each child.
element.props.children.forEach(child => {
render(child, dom);
});

container.appendChild(dom);
}

The last thing we need to do here is assign the element props to the node.

1
2
3
4
5
6
const isProperty = key => key !== "children"
Object.keys(element.props)
.filter(isProperty)
.forEach(name => {
dom[name] = element.props[name];
});
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
function createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map(child =>
typeof child === "object"
? child
: createTextElement(child)
),
},
}
}

function createTextElement(text) {
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: [],
},
}
}

function render(element, container) {
const dom =
element.type == "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(element.type)

const isProperty = key => key !== "children"
Object.keys(element.props)
.filter(isProperty)
.forEach(name => {
dom[name] = element.props[name]
})

element.props.children.forEach(child =>
render(child, dom)
)

container.appendChild(dom)
}
此页目录
2025-05-01 日报 Day173