Created
April 13, 2020 13:07
-
-
Save lqs469/9978c54b47c9f8bf738f525f8fe181e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const React = { | |
createElement(tag, props, ...children) { | |
if (typeof tag === 'function') { | |
try { | |
return tag(props); | |
} catch ({ promise, key }) { | |
promise.then((data) => { | |
console.log('catch', data, key); | |
fetchCache.set(key, data); | |
rerender(); | |
}); | |
return 'Loading'; | |
} | |
} | |
return { tag, props: { ...props, children: [...children] } }; | |
}, | |
}; | |
const states = []; | |
let stateId = 0; | |
const useState = (initalState) => { | |
const FROZENSTATEID = stateId; | |
states[FROZENSTATEID] = states[FROZENSTATEID] || initalState; | |
const setState = (newState) => { | |
states[FROZENSTATEID] = newState; | |
rerender(); | |
}; | |
stateId++; | |
return [states[FROZENSTATEID], setState]; | |
}; | |
const fetchCache = new Map(); | |
const useFetch = (fetch, key) => { | |
if (fetchCache.has(key)) { | |
return fetchCache.get(key); | |
} | |
throw { promise: fetch, key }; | |
}; | |
const App = () => { | |
const [name, setName] = useState('Allen'); | |
const [count, setCount] = useState(0); | |
const img = useFetch( | |
fetch('https://dog.ceo/api/breeds/image/random') | |
.then((res) => res.json()) | |
.then((data) => { | |
return data.message; | |
}), | |
'dog', | |
); | |
return ( | |
<div> | |
<h1 className="imClassName">Hello {name}</h1> | |
<input | |
placeholder="name" | |
value={name} | |
onchange={(e) => setName(e.target.value)} | |
/> | |
<div>{count}</div> | |
<button onclick={() => setCount(count + 1)}>+</button> | |
<button onclick={() => setCount(count - 1)}>-</button> | |
<p> | |
Labore esse aute aute mollit minim deserunt anim consequat dolor anim | |
nostrud cupidatat commodo sint. | |
</p> | |
<img src={img} /> | |
</div> | |
); | |
}; | |
const rerender = () => { | |
stateId = 0; | |
document.getElementById('root').firstChild.remove(); | |
render(<App />, document.getElementById('root')); | |
}; | |
const render = (reactElement, root) => { | |
if (typeof reactElement !== 'object') { | |
const text = document.createTextNode(reactElement); | |
root.appendChild(text); | |
return; | |
} | |
const el = document.createElement(reactElement.tag); | |
Object.keys(reactElement.props) | |
.filter((item) => item !== 'children') | |
.forEach((key) => { | |
el[key] = reactElement.props[key]; | |
}); | |
if (reactElement.props.children) { | |
reactElement.props.children.forEach((child) => { | |
render(child, el); | |
}); | |
} | |
root.appendChild(el); | |
}; | |
render(<App />, document.getElementById('root')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment