Skip to content

Instantly share code, notes, and snippets.

@lqs469
Created April 13, 2020 13:07
Show Gist options
  • Save lqs469/9978c54b47c9f8bf738f525f8fe181e0 to your computer and use it in GitHub Desktop.
Save lqs469/9978c54b47c9f8bf738f525f8fe181e0 to your computer and use it in GitHub Desktop.
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