Custom React

Create you own react library and JSX

Building a custom react:

Let's construct our own React and explore its behind-the-scenes workings.

File Name: index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Custom React App</title>
</head>

<body>
  <div id="root"></div>
  <script src="./customreact.js"></script>
</body>

</html>

File Name: customreact.js

function customeRender(reactElement, container) {
  const domElement = document.createElement(reactElement.type)
  domElement.innerHTML = reactElement.children
  domElement.setAttribute('href', reactElement.props.href)
  domElement.setAttribute('target', reactElement.props.target)

  container.appendChild(domElement)

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

const mainContainer = document.getElementById('root');

customeRender(reactElement, mainContainer)

The drawback of the above code is that it's hard-coded and repeats attributes, leading to issues when inserting more or fewer attributes.

Let's optimize the code above and enhance its modularity.

To create a modular customreact.js file, we utilize a loop that minimizes hard coding and repetition of attributes.

File Name: customreact.js

function customeRender(reactElement, container) {
  const domElement = document.createElement(reactElement.type)
  domElement.innerHTML = reactElement.children
  for (const prop in reactElement.props) {
    if (prop === 'children') continue;
    domElement.setAttribute(prop, reactElement.props[prop])
  }
  container.appendChild(domElement);
}

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

const mainContainer = document.getElementById('root');

customeRender(reactElement, mainContainer)
  • React understands a tree-like structure, behind the scenes, the bundler is used to transform your code into this tree-like syntax.

  • Every React uses bundlers like Webpack, Vite, etc.

Experimenting with the Vite project

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'

function MyApp() {
  return (
    <>
      <h1>Custom App!</h1>
    </>
  )
}

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

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

const anotherUser = "Mark"

const reactElement = React.createElement(
  'a',
  {
    href: 'https://google.com',
    target: '_blank'
  },
  'Click me to visit google',
  anotherUser
)

ReactDOM.createRoot(document.getElementById('root')).render(
  <App />
  // <MyApp /> // Working
  // MyApp() // Working
  // ReactElement // Not working
  // anotherElement // Working
  // reactElement // Working
)

Why ReactElement is not working?

React does not understand the syntax written by us; it recognizes specific syntax, such as createElement.

createElement allows you to create a React element. It provides an alternative to writing JSX.

Using JSX syntax like <MyApp /> is considered good practice in React. While using MyApp() will work, it is not recommended in React and should be used for fun only.

Injecting Variables or JavaScript Inside JSX

  • {variableName}: This is called an expression or evaluated expression. It means we cannot write JavaScript directly, but we can use the final outcome of JavaScript after evaluation.

  • Note: We cannot use arbitrary expressions inside JSX because, behind the scenes, Babel or another bundler may transpile your JSX into an object. Inside an object, we can only include evaluated expressions. Therefore, it's recommended to use only evaluated expressions within JSX.


Watch ReactJS series by Hitesh Choudhary