UNPKG

rax

Version:

A universal React-compatible render engine.

101 lines (85 loc) 2.94 kB
import Host from './host'; import createElement from '../createElement'; import instantiateComponent from './instantiateComponent'; import Root from './root'; import {INTERNAL, RENDERED_COMPONENT} from '../constant'; /** * Instance manager * @NOTE Key should not be compressed, for that will be added to native node and cause DOM Exception. */ const KEY = '_r'; export default { set(node, instance) { if (!node[KEY]) { node[KEY] = instance; // Record root instance to roots map if (instance.__rootID) { Host.rootInstances[instance.__rootID] = instance; Host.rootComponents[instance.__rootID] = instance[INTERNAL]; } } }, get(node) { return node[KEY]; }, remove(node) { let instance = this.get(node); if (instance) { node[KEY] = null; if (instance.__rootID) { delete Host.rootComponents[instance.__rootID]; delete Host.rootInstances[instance.__rootID]; } } }, mount(element, container, { parent, hydrate }) { if (process.env.NODE_ENV !== 'production') { Host.measurer && Host.measurer.beforeRender(); } const driver = Host.driver; // Real native root node is body if (container == null) { container = driver.createBody(); } const renderOptions = { element, container, hydrate }; // Before render callback driver.beforeRender && driver.beforeRender(renderOptions); // Get the context from the conceptual parent component. let parentContext; if (parent) { let parentInternal = parent[INTERNAL]; parentContext = parentInternal.__processChildContext(parentInternal._context); } // Update root component let prevRootInstance = this.get(container); if (prevRootInstance && prevRootInstance.__rootID) { if (parentContext) { // Using __penddingContext to pass new context prevRootInstance[INTERNAL].__penddingContext = parentContext; } prevRootInstance.__update(element); // After render callback driver.afterRender && driver.afterRender(renderOptions); return prevRootInstance; } // Init root component with empty children let renderedComponent = instantiateComponent(createElement(Root)); let defaultContext = parentContext || {}; let rootInstance = renderedComponent.__mountComponent(container, parent, defaultContext); this.set(container, rootInstance); // Mount new element through update queue avoid when there is in rendering phase rootInstance.__update(element); // After render callback driver.afterRender && driver.afterRender(renderOptions); if (process.env.NODE_ENV !== 'production') { // Devtool render new root hook Host.reconciler.renderNewRootComponent(rootInstance[INTERNAL][RENDERED_COMPONENT]); Host.measurer && Host.measurer.afterRender(); } return rootInstance; } };