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
Core Concepts:
React elements are JavaScript objects describing the DOM structure.
Rendering involves converting these objects into actual DOM nodes.
JSX Simplifies Everything:
- Writing JSX feels natural, but understanding
React.createElement
helps appreciate the magic behind the scenes.
- Writing JSX feels natural, but understanding
Attributes and Props:
- The
props
object is the backbone of how React (and my renderer) handles attributes and children.
- The
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. 🚀
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