Skip to content

Instantly share code, notes, and snippets.

@LiuuY
Created September 30, 2016 02:29
Show Gist options
  • Save LiuuY/f7b77b2cf317fd90d2789af3e50c1dfa to your computer and use it in GitHub Desktop.
Save LiuuY/f7b77b2cf317fd90d2789af3e50c1dfa to your computer and use it in GitHub Desktop.
Naïve React (no updates 😛) in 60 lines https://twitter.com/dan_abramov/status/781620845185732608
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
// https://twitter.com/dan_abramov/status/781620845185732608
// http://jsbin.com/qiguyibolu/1/edit?html,js,output
function isClass(type) {
// React.Component subclasses have this flag
return type.prototype && Boolean(type.prototype.isReactComponent);
}
function mountComposite(element) {
var type = element.type;
var props = element.props;
var renderedElement;
if (isClass(type)) {
// Component class
var instance = new type(props);
instance.componentWillMount();
renderedElement = instance.render();
} else if (typeof type === 'function') {
// Component function
renderedElement = type(props);
}
// Mount the rendered output
return mount(renderedElement);
}
function mountHost(element) {
var type = element.type;
var props = element.props;
var children = props.children;
// This block of code shouldn't be in the reconciler.
// Different renderers might initialize nodes differently.
// For example, React Native would create iOS or Android views.
var node = document.createElement(type);
Object.keys(props).forEach(propName => {
if (propName !== 'children') {
node.setAttribute(propName, props[propName]);
}
});
// Mount the children
children.filter(Boolean).forEach(childElement => {
var childNode = mount(childElement);
// This line of code is also renderer-specific.
// It would be different depending on the renderer:
node.appendChild(childNode);
});
// Return the DOM node as mount result
return node;
}
function mount(element) {
var type = element.type;
if (typeof type === 'function') {
// User-defined components
return mountComposite(element);
} else if (typeof type === 'string') {
// Platform-specific components
return mountHost(element);
}
}
// ----------------------------
// Necessary for JSX to work
window.React = {
createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children || props.children
}
}
}
};
function Button() {
return <div class="button" />;
}
function App() {
return (
<div>
<Button />
<Button />
<Button />
</div>
);
}
var rootEl = document.getElementById('root');
var node = mount(<App />);
rootEl.appendChild(node);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment