-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
105 lines (94 loc) · 2.77 KB
/
index.tsx
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
let React = {
createElement: (tag, props, ...children) => {
if (typeof tag == "function") {
try {
return tag(props);
} catch ({ promise, key }) {
promise.then((data) => {
console.log(promise);
promiseCache.set(key, data);
rerender();
});
return { tag: "h1", props: { children: ["I AM LOADING"] } };
}
}
var element = { tag, props: { ...props, children } };
// console.log( element );
return element;
},
};
//to know if data is ready we implement cache, a closure, not global
const promiseCache = new Map();
const createResouce = (thingThatReturnsSomething, key) => {
if (promiseCache.has(key)) {
return promiseCache.get(key);
}
throw { promise: thingThatReturnsSomething(), key };
};
const App = () => {
const [name, setName] = useState("person");
const [count, setCount] = useState(0);
const dogPhotoUrl = createResouce(
() =>
fetch("https://dog.ceo/api/breeds/image/random")
.then((r) => r.json())
.then((payload) => payload.message),
"dogPhoto"
);
return (
<div className="react-2020">
<h1>Hello, {name}!</h1>
<input
value={name}
onchange={(e) => setName(e.target.value)}
type="text"
placeholder="name"
/>
<h2>The count is: {count}</h2>
{dogPhotoUrl}
<button onclick={() => setCount(count + 1)}>+</button>
<button onclick={() => setCount(count - 1)}>-</button>
<p>Yes</p>
</div>
);
};
//Moving parts of our app
const states = [];
let stateCursor = 0;
const useState = (initialState) => {
const FROZENCURSOR = stateCursor;
states[FROZENCURSOR] = states[FROZENCURSOR] || initialState;
console.log(states);
const setState = (newState) => {
states[FROZENCURSOR] = newState;
rerender();
};
stateCursor++;
return [states[FROZENCURSOR], setState];
};
const renderer = (reactElement, container) => {
if (["string", "number"].includes(typeof reactElement)) {
container.appendChild(document.createTextNode(String(reactElement)));
return;
}
const actualDomElement = document.createElement(reactElement.tag);
if (reactElement.props) {
Object.keys(reactElement.props)
.filter((p) => p != "children")
.forEach((p) => (actualDomElement[p] = reactElement.props[p]));
}
if (reactElement.props.children) {
reactElement.props.children.forEach((child) =>
renderer(child, actualDomElement)
);
}
//append root to the container
container.appendChild(actualDomElement);
};
const rerender = () => {
stateCursor = 0;
document.querySelector("#app").firstChild.remove();
renderer(<App />, document.querySelector("#app"));
};
//windows.app the id is also a variable
renderer(<App />, document.querySelector("#app"));