-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
67 lines (63 loc) · 1.87 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
import ReactDOM from './ReactDOM';
import './index.css';
export const globalState = [];
export let stateCursor = 0;
const React = {
createElement: function (type, props, ...children) {
if (typeof type === 'function') {
return type();
}
const element = { type, props: { ...props, children } };
return element;
},
useState: function (initialState) {
const FROZENCURSOR = stateCursor;
globalState[FROZENCURSOR] = globalState[FROZENCURSOR] || initialState;
let setState = (newState) => {
// setState for every useState call has closure over FROZENCURSOR for that call and each setState exactly knows which index it has to update.
globalState[FROZENCURSOR] = newState;
// for this to work we need to set stateCursor to zero in re-render
rerender();
};
stateCursor++;
return [globalState[FROZENCURSOR], setState];
},
};
const App = () => {
const [name, setName] = React.useState('Hridayesh');
return (
<div class='parent'>
<h1>Building React from Scratch</h1>
<span>Copyright 2022</span>
<p>Hello {name}!</p>
<input
type='text'
name='person'
value={name}
onchange={(e) => {
setName(e.target.value);
}}
/>
<div style='margin: 16px'>
<Counter />
</div>
</div>
);
};
const Counter = () => {
const [count, setCount] = React.useState(0);
return (
<div>
<button onclick={() => setCount(count - 1)}>-</button>
{count}
<button onclick={() => setCount(count + 1)}>+</button>
</div>
);
};
// just for re rendering after state update. React doesn't work like this for re-rendering
export const rerender = () => {
stateCursor = 0;
document.querySelector('#app').firstChild.remove();
ReactDOM.render(<App />, document.querySelector('#app'));
};
ReactDOM.render(<App />, document.querySelector('#app'));