How I Built My Own React Renderer

What Is React Rendering?

At its core, React renders user interfaces by converting JavaScript objects (React elements) into DOM elements. React elements are essentially descriptions of the UI in the form of plain JavaScript objects. React then uses these descriptions to manipulate the DOM efficiently.

For example, in React, you might write:

const element = <a href="https://google.com" target="_blank">Visit Google</a>;

Behind the scenes, this is equivalent to:

const element = React.createElement(
  'a',
  { href: 'https://google.com', target: '_blank' },
  'Visit Google'
);

The React.createElement function creates an object that looks like this:

{
  type: 'a',
  props: {
    href: 'https://google.com',
    target: '_blank',
    children: 'Visit Google'
  }
}

Building My Custom Renderer

Inspired by React’s approach, I decided to write my own renderer called customRender. This renderer takes a React-like object and renders it into a container in the DOM.

Here's the complete code for the custom renderer:

function customRender(reactElement, container) {
  // Create a DOM element based on the React-like type
  const domElement = document.createElement(reactElement.type);

  // Add children (innerHTML)
  domElement.innerHTML = reactElement.children;

  // Add all props as attributes, except children
  for (const prop in reactElement.props) {
    if (prop !== 'children') {
      domElement.setAttribute(prop, reactElement.props[prop]);
    }
  }

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

React Element Simulation

I created a simple React-like element manually:

const reactElement = {
  type: 'a',
  props: {
    href: 'https://google.com',
    target: '_blank',
  },
  children: 'Click me to visit Google',
};

Rendering the Element

I passed the reactElement object to my custom renderer, along with a DOM container:

const mainContainer = document.querySelector('#root');
customRender(reactElement, mainContainer);

This rendered the following HTML:

<a href="https://google.com" target="_blank">Click me to visit Google</a>

Comparison with React

Using React, you’d typically write this in JSX:

const element = (
  <a href="https://google.com" target="_blank">Visit Google</a>
);

Or, using React.createElement:

const element = React.createElement(
  'a',
  { href: 'https://google.com', target: '_blank' },
  'Visit Google'
);

In both cases, React internally converts these to a JavaScript object like the one I manually created earlier and renders it to the DOM efficiently using its Virtual DOM.


Lessons Learned

  1. Core Concepts:

    • React elements are JavaScript objects describing the DOM structure.

    • Rendering involves converting these objects into actual DOM nodes.

  2. JSX Simplifies Everything:

    • Writing JSX feels natural, but understanding React.createElement helps appreciate the magic behind the scenes.
  3. Attributes and Props:

    • The props object is the backbone of how React (and my renderer) handles attributes and children.
  4. Room for Growth:

    • My renderer is basic and doesn’t handle updates or nested elements, but it’s a great starting point for learning.

My Implementation in Vite

I also used Vite with React to experiment with both my custom renderer and React’s createElement. Here's a simple implementation:

import React from 'react';
import { createRoot } from 'react-dom/client';

const App = () => (
  <div>
    <a href="https://google.com" target="_blank">Visit Google</a>
  </div>
);

createRoot(document.getElementById('root')).render(<App />);

Conclusion

This experiment reinforced the importance of understanding the tools we use daily. Building something similar to React, even at a small scale, gave me a new appreciation for its power and efficiency. If you’ve ever been curious about how React works, I encourage you to try building your own custom renderer—it’s simpler than you think!

Let me know what you think in the comments or if you’ve ever built something similar. 🚀


0
Subscribe to my newsletter

Read articles from Sahana S Acharya directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sahana S Acharya
Sahana S Acharya