Didact: Rendering DOM elements
[Update] This post is based on the old React architecture, there’s a new self-contained post where we build everything from scratch including hooks, concurrent mode, fibers, etc.
This story is part of a series where we build own version version of React step by step:
DOM review
Before we start, let’s review the DOM API we will be using:
Note that we are setting the element properties instead of attributes. This means that only valid properties will be allowed.
Didact Elements
We will use plain JS objects to describe what needs to be rendered. We’ll call them Didact Elements. These elements have two required properties: type
and props
. type
can be a string or a function, but we will use only strings until we introduce components on a later post. props
is an object that could be empty (but not null). props
may have a children
property, which should be an array of Didact Elements.
We will be using Didact Elements a lot, so from now on we will just call them elements. Not to be confused with HTML Elements, those we will call DOM elements, or just
dom
when naming variables (as preact does).
For example, an element like this one:
Describes this dom:
Didact elements are pretty similar to React elements. But usually you don’t create React elements as JS objects when using React, you probably use JSX or even createElement
. We will do the same in Didact, but we are leaving the element creation code for the next post in the series.
Render DOM Elements
Next step is to render an element and its children to the dom. We we’ll use a render
function (equivalent to ReactDOM.render
) receiving an element and a dom container. The function should create the dom sub-tree defined by the element and append it to the container:
We are still missing properties and event listeners. Let’s iterate over props
properties names with the Object.keys
function and set them accordingly:
Render DOM Text Nodes
One thing the render
function does not support yet is text nodes. First we need to define how text elements look like. For example, an element describing <span>Foo</span>
looks like this in React:
Note that the child, instead of being another element object, is just a string. That goes against how we defined Didact Elements:children
should be an array of elements and all elements should have type
and props
. If we follow those rules we will have less if
s in the future. So, Didact Text Elements will have a type
equals to “TEXT ELEMENT” and the actual text will be in a nodeValue
property. Like this:
Now that we defined how text elements look like we can render them. The difference with other element is that text elements, instead of using createElement
should use createTextNode
. That’s it, the nodeValue
will be set in the same way as other properties.
Summary
We’ve created a render
function that allow us to render an element an its children to the DOM. Next thing we need is an easy way to create elements. We’ll do that in the next post, where we’ll make JSX work with Didact.
If you want to try the code we have written so far, check this codepen. You can also check this diff from the github repo.
Next post:
Thanks for reading.