Didact: Element creation and JSX
[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 of React step by step:
JSX
Last time we introduced Didact Elements, which are a very verbose way to describe what we want to get rendered to the DOM. In this post we will see how to simplify the creation of elements using JSX.
JSX provides some syntactic sugar to create elements. Instead of:
We can have:
If you are not familiar with JSX you may be wondering if the last snippet is valid javascript: it’s not. To make browsers understand it, the code needs to be transformed to valid JS by a preprocessor, like babel (to know more about JSX read this post by Jason Miller). For example, babel transpiles the JSX from above to:
The only thing we need to add to Didact to support JSX is a createElement
function, and that’s all, the rest of the work is done by the preprocessor. The first argument of the function is the type
of the element, the second is an object with element props
, and all the following arguments are children
. createElement
needs to create a props
object, assign it all the values from the second argument, set the children
property to an array with all the arguments after the second, and then return an object with type
and props
. It’s easier to put it into code:
This function works well except from one thing: text elements. Text children are passed as strings to the createElement
function, and Didact needs the text elements to have type
and props
as the rest of the elements. So we will convert to a text element every arg that isn’t yet an element:
I also filtered the list of children to exclude null
, undefined
and false
args, we won’t render those so there is no need to add them to props.children
.
Summary
We haven’t added any real power to Didact in this post, but we now have an improved developer experience since we can use JSX to define elements. I’ve updated the codepen from last time to include the code from this post. Note that the codepen is using babel to transpile the JSX, the comment at the beginning /** @jsx createElement */
tells babel with function to use.
You can also check the changes from the commit on Github.
In the next post we introduce Didact’s virtual DOM and the reconciliation algorithm to support DOM updates:
Thanks for reading.