Created
August 26, 2017 05:03
-
-
Save rmccue/94d409a16d03c51eb4acdebdd931c893 to your computer and use it in GitHub Desktop.
not-react.js
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
// Resolve custom components by calling .render() recursively. | |
const resolveComponents = element => { | |
// If the "component" is a string, it's static text. | |
if ( typeof element === 'string' ) { | |
return element; | |
} | |
// If the type is a string, it's already in DOM node form. | |
if ( typeof element.type === 'string' ) { | |
return element; | |
} | |
// The type is a component class, instantiate it with props | |
// and call .render() | |
const inst = new element.type( element.props || {} ); | |
return resolveComponents( inst.render() ); | |
}; | |
// Turn a list of elements (possibly with children) into a list of DOM nodes. | |
const treeToElements = tree => { | |
return tree.map( node => { | |
// First, resolve custom components with .render() | |
const element = resolveComponents( node ); | |
// If the element is just a string, it's text. | |
if ( typeof element === 'string' ) { | |
return document.createTextNode( element ); | |
} | |
// Create a DOM element of the given type. | |
const domEl = document.createElement( element.type ); | |
// Extract special props, and collect the rest to set on the element. | |
const { children, key, ref, ...props } = element.props; | |
if ( props ) { | |
// If the element has properties, set them on the DOM element now. | |
Object.keys( props ).forEach( key => { | |
domEl[ key ] = props[ key ]; | |
}); | |
} | |
if ( children ) { | |
// If the element has children, resolve them also. | |
const childElements = treeToElements( children ); | |
// Then append to our node. | |
childElements.forEach( child => domEl.appendChild( child ) ); | |
} | |
return domEl; | |
} ); | |
}; | |
const ReactDOM = { | |
render: ( component, root ) => { | |
// Take our main component and turn it into a tree of DOM elements. | |
const toRender = treeToElements( [ component ] ); | |
// Then, add the main DOM element to the root. | |
root.appendChild( toRender[0] ); | |
}, | |
}; | |
export default ReactDOM; |
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
// Base component class. | |
export class Component { | |
constructor( props ) { | |
this.props = props; | |
this.state = {}; | |
} | |
render() {} | |
} | |
// Build an element (typically called from JSX) | |
const createElement = (type, props, ...children) => { | |
return { | |
type, | |
props: { ...props, children }, | |
}; | |
}; | |
const React = { | |
Component, | |
createElement, | |
}; | |
export default React; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment