Building a Custom React from Scratch with Vanilla JavaScript

React is one of the most popular JavaScript libraries for building user interfaces, especially single-page applications. But have you ever wondered what happens under the hood when React renders an element? In this blog, we'll explore this by creating a very basic version of React using plain JavaScript.

Our goal is to understand the fundamental concepts behind React's rendering process, not to create a full-fledged React clone. By the end of this tutorial, you'll have a better grasp of how React works and some cool insights into how you can manipulate the DOM directly.

Setting Up the HTML

Before we dive into the JavaScript, let's start with the HTML structure. Our HTML file is minimal because most of the work will be done in JavaScript.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom React</title>
</head>
<body>
    <div id="root"></div> <!-- This is where our custom React element will be rendered -->
    <script src="./custom.js"></script> <!-- Our custom React logic will be in this script -->
</body>
</html>

Here, we have a single div with an id of root. This div will act as the container where we'll render our custom React elements. The script tag points to custom.js, where our custom React code will live.

Defining the React Element

In React, elements are objects that describe what you want to see on the screen. These objects have properties like type, props, and children. Let’s create a simple version of a React element using plain JavaScript.

const reactElement = {
    type: 'a', // The type of element to create (in this case, an anchor tag)
    props: {
        href: "https://google.com", // The URL the anchor tag will link to
        target: '_blank' // Open the link in a new tab
    },
    children: 'Click me to visit Google' // The text content inside the anchor tag
}

Here’s what each property does:

  • type: The type of the HTML element (like div, span, a, etc.).

  • props: An object containing the element’s attributes, such as href and target for an anchor tag.

  • children: The content inside the element, which can be text or even other elements.

Creating the Render Function

Now that we have our React element defined, let's create a function that will render it to the DOM. This function will take our reactElement object and a container in which to render the element.

function customRender(reactElement, container) {
    // Create the DOM element using the type specified in the reactElement
    const domElement = document.createElement(reactElement.type);

    // Set innerHTML to the text content specified in reactElement's children
    domElement.innerHTML = reactElement.children; 

    // Loop through the props and assign them to the DOM element
    for (const prop in reactElement.props) {
        domElement.setAttribute(prop, reactElement.props[prop]);
    }

    // Append the newly created DOM element to the container
    container.appendChild(domElement);
}

Breaking Down the Render Function:

  1. Creating the DOM Element:

    • The function starts by creating a new DOM element using document.createElement(reactElement.type). This will be an anchor (<a>) in our case.
  2. Setting the Content:

    • domElement.innerHTML = reactElement.children; sets the inner HTML of our anchor tag to 'Click me to visit Google'.
  3. Applying Attributes:

    • The props object contains the attributes for our anchor tag. We loop through each key in props and apply it to the DOM element using setAttribute.
  4. Appending to the Container:

    • Finally, we add the newly created element to the container (which is the #root div in our HTML).

Rendering to the DOM

The last step is to actually render our element to the DOM by calling customRender and passing in our reactElement and the container.

// Select the container in which the element will be rendered
const mainContainer = document.querySelector('#root');

// Call the customRender function to render the element
customRender(reactElement, mainContainer);

This code selects the #root div and calls customRender to append our anchor tag to it. When you open the HTML file in your browser, you should see a link that says "Click me to visit Google". Clicking this link will open Google in a new tab.

Conclusion

Congratulations! You've just built a simple version of React's rendering engine using vanilla JavaScript. While this is a very basic implementation, it covers the core concepts of how React creates and renders elements to the DOM.

This example helps to demystify React’s inner workings and gives you a foundation to explore more complex topics, such as handling events, managing state, and rendering lists of elements. As you continue to learn, you’ll see how React’s virtual DOM optimizes this process for performance and flexibility.

Feel free to experiment with this code and try adding more elements, handling events, or even building a small component-based UI. The possibilities are endless!

If you found this tutorial helpful, please share it with others and let me know your thoughts in the comments. Happy coding!