Building React in Vanilla JS : 101 - createElement and render

I'm Yogesh Kanwade, a final year Computer Engineering student with a deep passion for software development. I am a continuous learner, with hardworking and goal-driven mindset and strong leadership capabilities. I am actively exploring the vast possibilities of Web Development along with AWS and DevOps, fascinated by their impact on scalable and efficient web solutions.
The Basics
A simple Button placed in our container app . We increment score on button click and re-render our page entirely using our render() function.
let score = 0;
function render() {
const parentDiv = document.getElementById("app");
parentDiv.innerHTML = "";
const button = document.createElement("button");
button.innerHTML = Score ${score};
parentDiv.appendChild(button);
button.addEventListener("click", function incrementScore() {
score++;
render();
});
}
render();
We can go to next step where we introduce Component-like Abstraction. Lets write a function that creates our Button element by taking in the button text and onClick function as parameters.
function Button(text, onClick) {
const btn = document.createElement("button");
btn.textContent = text;
btn.addEventListener("click", onClick);
return btn;
}
Our createElement
We would not be just creating buttons. We can make our function more generic so as to create any HTML element. Lets try to replicate React’s React.createElement. We will start with supporting a type (HTML element), props (for onClick) and children (for button text).
let score = 0;
const incrementScore = () => {
score++;
render();
};
const createElement = (type, props = {}, child) => {
const element = document.createElement(type);
for (const [key, value] of Object.entries(props)) {
if (key.startsWith("on") && typeof value === "function") {
const event = key.slice(2).toLowerCase();
const callbackFunction = value;
element.addEventListener(event, callbackFunction);
}
}
if (typeof child === "string") {
const textNode = document.createTextNode(child);
element.appendChild(textNode);
}
return element;
};
function render() {
const parentDiv = document.getElementById("app");
parentDiv.innerHTML = "";
const text = `score ${score}`;
const button = createElement(
"button",
{ onClick: () => incrementScore() },
text
);
parentDiv.appendChild(button);
}
render();



