FrontendPro

111Implement a minimal React-like renderer with virtual DOM diffing and keyed reconciliation

hardAbout 75 minutesCodingvirtual-domreconciliationdomreact-internals

Problem

Build the core of a React-like library, without React:

  • h(type, props, ...children) creates a virtual node { type, props, children, key }. type is a tag name or a function component ((props) => vnode). Strings and numbers become text nodes; null, undefined and booleans render nothing; nested arrays are flattened. key comes from props.key.
  • render(vnode, container) mounts on the first call and patches on later calls, reusing existing DOM nodes wherever possible.

Patching rules:

  • Same type: update the existing DOM node's props and diff its children. Different type: replace the node.
  • Props: attributes (removed when absent), className, style objects (removing old keys), and on* event handlers (onClick → click), replaced without stacking listeners.
  • Children: keyed children are matched by key and moved (the same DOM node), so state like an input's value survives reordering. Unkeyed children are matched by position.
render(h("ul", null, items.map((item) => h("li", { key: item.id }, item.text))), root);

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Video walkthrough

Stuck? Watch someone solve it, then try again on your own.

Rodrigo Pombo - Build your own React - jsday 2019GrUSP on YouTubeOpen on YouTube

Step-by-step

Flatten arrays, drop null, undefined and booleans, and wrap strings and numbers as { type: "#text", props: { nodeValue } }. Every child is then a vnode, which keeps the diff code simple.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever