We can't write React.createElement() every time to create a virtual DOM. Therefore we need some sort of syntax for converting what we write into React.createElement calls.This syntax is called JSX.
Cons of React.createElement
Writing this every time to create an element is tedious
Nesting of elements inside the brackets if the root element and last child has more element in between
We can't track every element's child and attribute
How it all fits together?
When we use React, we usually have one index.html which has one tag <div id='root'>. There will be an index.js that has document.getElementById('root').Obviously, these two files must be connected and one thing to note here is that all UI/UX displays of the react application stem out from index.html.This concept is called Single Page Application. This essentially means we all the different content we render through react component will have the parent tag 'div' with id='root'.
We can create as many functional components we want. Those functions can be imported into another component by import statements.UI part of that imported function can be merged into the parent function(function which imports) through JSX. This is the perfect use case of JSX.
JSX will be like HTML like tag and its tag name will be imported function name. See this example below
Basically, all react components we create boils down to HTML tags like <div>, <h1>, <p> etc.Therefore JSX may contain HTML tags but with lower cases and other imported functional component(like <Example />)
Note: Same happens in a nested child relationship with the third argument in createElement method takes the nested child
Also, remember React.createElement returns plain JS object with keys - type, key, ref, props, _owner, _store. This creates virtual DOM.