How to Recreate React Features Using Only Vanilla JavaScript
As a web developer, understanding the underlying principles of popular libraries and frameworks can be incredibly valuable. In this article, we'll explore how to implement a basic React-like functionality using only vanilla JavaScript. By understanding the mechanics behind React, you'll gain a deeper appreciation for the design choices and capabilities of this powerful library.
React Fundamentals
Before diving into the implementation, let's quickly review the key concepts in React:
Components: React allows you to build your application as a tree of reusable components, each responsible for rendering a piece of the UI.
Props: Components receive data from their parent components through "props," which are essentially attributes passed down to the child components.
State: Components can manage their own internal state, which can be updated to trigger re-renders and update the displayed UI.
Virtual DOM: React uses a virtual DOM, a lightweight in-memory representation of the actual DOM. This allows it to efficiently update the real DOM by only making the necessary changes.
Vanilla JS Implementation
Now, let's see how we can implement a basic React-like functionality using plain JavaScript:
function renderReactElement(reactElement, mainContainer) {
// Create a new DOM element based on the 'type' property of the reactElement
const element = document.createElement(reactElement.type);
// Set the innerHTML of the element to the 'children' property
element.innerHTML = reactElement.children;
// Iterate over the 'props' object and set the corresponding attributes or event listeners
Object.entries(reactElement.props).forEach(([propName, propValue]) => {
// If the prop name starts with 'on', assume it's an event listener and add it to the element
if (propName.startsWith('on') && typeof propValue === 'function') {
const eventName = propName.toLowerCase().substring(2);
element.addEventListener(eventName, propValue);
} else {
// Otherwise, set the prop as an attribute on the element
element.setAttribute(propName, propValue);
}
});
// Append the created element to the main container
mainContainer.appendChild(element);
}
// Create a React-like element
const reactElement = {
type: 'button',
props: {
id: 'container',
className: 'my-container',
onClick: () => alert('Welcome :)'),
},
children: 'Click On ME',
};
// Get the main container element
const mainContainer = document.getElementById('root');
// Render the React-like element to the main container
renderReactElement(reactElement, mainContainer);
The key steps in this implementation are:
Create a new DOM element based on the
type
property of thereactElement
object.Set the
innerHTML
of the element to thechildren
property.Iterate over the
props
object and set the corresponding attributes or event listeners on the element.Append the created element to the
mainContainer
.
This vanilla JavaScript approach allows you to create and render a basic React-like element without the use of any libraries or frameworks. However, it lacks some of the advanced features and capabilities that React provides, such as the virtual DOM, efficient updates, and state management.
Comparison to React
Let's compare the vanilla JavaScript implementation to how React would handle the same functionality:
React Approach:
const MyButton = ({ onClick, children }) => {
return (
<button id="container" className="my-container" onClick={onClick}>
{children}
</button>
);
};
const App = () => {
const handleClick = () => {
alert('Welcome :)');
};
return (
<div id="root">
<MyButton onClick={handleClick}>Click On ME</MyButton>
</div>
);
};
The key differences between the two approaches are:
Component Encapsulation: In React, the button logic is encapsulated within the
MyButton
component, making it more reusable and easier to manage.Declarative Syntax: React's JSX syntax allows you to declare the UI structure more declaratively, without having to manually create and manipulate DOM elements.
Virtual DOM: React uses a virtual DOM, which allows it to efficiently update the actual DOM by only making the necessary changes, unlike the direct DOM manipulation in the vanilla JavaScript approach.
State Management: React provides built-in state management capabilities, making it easier to handle dynamic updates and interactions within your application.
Lifecycle Methods: React components have access to lifecycle methods, which allow you to perform actions at different stages of the component's lifecycle, such as when it's mounted, updated, or unmounted.
Overall, the React approach is more concise, declarative, and easier to manage, especially as the complexity of the application grows. The vanilla JavaScript implementation, while functional, requires more manual DOM manipulation and doesn't provide the same level of abstraction and tooling that React offers.
Conclusion
In this article, we've explored how to implement a basic React-like functionality using vanilla JavaScript. By understanding the underlying mechanics of React, you'll gain a deeper appreciation for the design choices and capabilities of this powerful library.
While the vanilla JavaScript approach demonstrates the core concepts, it lacks the advanced features and tooling that React provides. As you continue your web development journey, exploring and understanding the internals of popular frameworks and libraries can help you make more informed decisions and better understand the trade-offs between different approaches.
Subscribe to my newsletter
Read articles from Naitik Prajapati directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Naitik Prajapati
Naitik Prajapati
I am a dedicated Full-Stack Developer with a strong passion for creating innovative web applications. Proficient in both front-end and back-end technologies, I excel in HTML, CSS, JavaScript, React.js, and Node.js, and have experience with database management systems like PostgreSQL and MySQL. As a third-year student, I combine technical expertise with a keen understanding of user experience to build robust, user-friendly applications.