diff --git a/src/reconciler.js b/src/reconciler.js index 45eff5f..585b0f6 100644 --- a/src/reconciler.js +++ b/src/reconciler.js @@ -1,4 +1,24 @@ -export function render(element, parentDom) { +let rootInstance = null; + +export function render(element, container) { + const prevInstance = rootInstance; + const nextInstance = reconcile(container, prevInstance, element); + rootInstance = nextInstance; +} + +function reconcile(parentDom, instance, element) { + if (instance == null) { + const newInstance = instantiate(element); + parentDom.appendChild(newInstance.dom); + return newInstance; + } else { + const newInstance = instantiate(element); + parentDom.replaceChild(newInstance.dom, instance.dom); + return newInstance; + } +} + +function instantiate(element) { const { type, props } = element; // Create DOM element @@ -20,10 +40,12 @@ export function render(element, parentDom) { dom[name] = props[name]; }); - // Render children + // Instantiate and append children const childElements = props.children || []; - childElements.forEach(childElement => render(childElement, dom)); + const childInstances = childElements.map(instantiate); + const childDoms = childInstances.map(childInstance => childInstance.dom); + childDoms.forEach(childDom => dom.appendChild(childDom)); - // Append to parent - parentDom.appendChild(dom); + const instance = { dom, element, childInstances }; + return instance; } diff --git a/test/02.re-render-element.test.js b/test/02.re-render-element.test.js new file mode 100644 index 0000000..28ff94a --- /dev/null +++ b/test/02.re-render-element.test.js @@ -0,0 +1,26 @@ +import test from "ava"; +import browserEnv from "browser-env"; +/** @jsx createElement */ +import { render, createElement } from "../src/didact"; + +// Create document global var +browserEnv(["document"]); + +test.beforeEach(t => { + let root = document.getElementById("root"); + if (!root) { + root = document.createElement("div"); + root.id = "root"; + document.body.appendChild(root); + } + t.context.root = root; +}); + +test("render jsx div", t => { + const root = t.context.root; + const element =