React Internals
Dilip Agheda
Software Engineer - Fullstack JavaScript | React | TypeScript | Node.js | Cypress | Selenium | C# | Test Automation | AWS
Why component names begin with a capital letter?
If you have been using React for sometime, you must have noticed that custom component name starts with a capital letter.
e.g.,
const Hello = (props) =>
{
return (
? ? ? <div>Hello</div>
? ? )
}{
Why the name for this component is Hello and not hello ?
In order to understand this, we need to dive little bit into React internals. The code above is using what is called JSX which looks like HTML but its not. it is a special syntax devised by React team and is part of React as such. It is essentially a syntactic sugar representing regular JavaScript function calls. When this component gets built by the build tool, at some point Babel compiler kicks in and converts this JSX into regular JavaScript.
Babel is the compiler that converts JSX into regular JavaScript.
React documentation describes how to write React component without JSX. Understanding that is critical to grasp what Babel compiler is doing under the hood.
If you are interested in reading more about it on official documentation, please refer it here - React without JSX
We can rewrite above component without JSX like so:
const Hello = props =>
? return React.createElement("div", null, "Hello");
};
This looks just like a regular JavaScript. Nothing fancy! React.createElement is a function which is invoked by passing different parameters. The first parameter is "div" which is the name of an element we are trying to render. The 3rd parameter is "Hello" which is a child of the element "div".
Now, here is an interesting part. The first parameter can also be a function which then returns an output of another call of React.createElement. This is the pattern that allows component composition like below.
Fundamental design pattern in React is 'composition'.
const Hello = (props) =>
{
return (
? ? ? <div>Hello</div>
? ? )
}
const World = (props) => {
? return? (
? ? <span>World</span>
? )
}
const App = (props) => {
? return (
? ? <div>
? ? ? <Hello />
? ? ? <World />
? ? </div>
? )
}
In above code, App is the component formed using composing of components Hello and World. If you wonder what gets spitted out by Babel compiler, copy and paste this code into any of the online Babel compiler. Let's try this one. babeljs.io
领英推荐
The babel output is
"use strict"
const Hello = props => {
? return /*#__PURE__*/React.createElement("div", null, "Hello");
};
const World = props => {
? return /*#__PURE__*/React.createElement("span", null, "World");
};
const App = props => {
? return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Hello, null), /*#__PURE__*/React.createElement(World, null));
};;
Take a look at React.createElement calls carefully in App function. The first parameter is a function namely Hello and World.
Now, try changing component name of World to world. If you are thinking that it's just some weird naming convention in my codebase, you will be surprised!
See what I got from Babel!
"use strict"
const Hello = props => {
? return /*#__PURE__*/React.createElement("div", null, "Hello");
};
const world = props => {
? return /*#__PURE__*/React.createElement("span", null, "World");
};
const App = props => {
? return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Hello, null), /*#__PURE__*/React.createElement("world", null));
};;
Look at App function and last call to React.createElement. See the first parameter is wrapped inside a quote. Babel thinks that "world" is kind of equivalent to "div" or "span" or "p" and will try to take that literally.
Obviously this code will not work as expected and you might get weird errors on browser.
Summary
React.createElement can take first parameter as a string in which case it will try to render that element just like that.
e.g.,
React.createElement("span",null,"Hi there!")
will spit out span element with text Hi there! in it.
React.createElement can also take first parameter as a function in which case it will execute it and replace the first param with its output.
The decision taken by Babel whether to put the first param as a string or as a function call is driven by this naming convention of component starting with first letter as capital.
Babel compiler itself is written in JavaScript
If you are wondering why a complex thing like a Babel compiler can work inside a browser in a tool like babeljs.io ? That's because its written in JavaScript and can be imported as a regular bundle.