React - Learn From Scratch - Part Two

In Part One, we learned how we can create a simple React element and add it in our page. You may check Part 1 here.
 
This was the state of our index.html page after the first part.
  1. <html>    
  2. <head>    
  3.     <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>    
  4.     <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>    
  5. </head>    
  6. <body>    
  7.     <div id="app">    
  8.             
  9.     </div>    
  10.     <script>    
  11.         // if(React){    
  12.         //     alert('React is available')    
  13.         // }    
  14.         var el = React.createElement('h3',{id:'myheader',class:'test'},"Bilal Shahzad");    
  15.         ReactDOM.render(el,document.getElementById('app'));    
  16.     </script>    
  17. </body>    
  18. </html>     

Function Component

 
Now let’s move element creation logic into a function and see another version of React.createElement() function.
  1. <script>  
  2.         function MyName(props){  
  3.             return React.createElement('h3',{id:'myheader',class:'test'},props.name);  
  4.         }  
  5.         var el = React.createElement(MyName, {name:"Bilal Shahzad"});  
  6.         ReactDOM.render(el,document.getElementById('app'));  
  7.     </script>  
Explanation
 
We’ve moved our h3 element creation logic into a function. This function can be called “Function Component” in React. It is receiving an object which contains properties. Normally this is called “props” in React. (The name of variable can be anything). The function is creating React element and returning it. This function can be used multiple times now (reusability). Then we’ve passed function name to React.createElement() function as first parameter & passed properties (data/props) as second parameter. And then we’ve rendered this in our page DOM. Run page and check if it is still working.
 
Let’s create another component (function) which will create a profile link using anchor tag. We’ll pass properties (or dynamic content) as props to the function so it can be re-used with different content.
  1. <script>  
  2.         function ProfileLink(props){  
  3.             var url = props.url;  
  4.             var txt = props.urlText;  
  5.             return React.createElement('a',{href:props.url},txt);  
  6.         }  
  7.         var dataToPass = {url:"https://www.youtube.com/c/LearnInUrdu139",urlText: "Learn in Urdu Tutorials"};  
  8.         var el = React.createElement(ProfileLink, dataToPass);  
  9.   
  10.         ReactDOM.render(el,document.getElementById('app'));  
  11.     </script>  
Explanation
 
We’ve intentionally removed MyName component for the time being. We’ve created a new function component which is responsible to render a hyperlink. “props” contains URL & Anchor Text as we’ve passed it while using component.
 
You may have noticed that ReactDOM.render() is taking one element as first parameter. What if we want to render multiple elements instead (i.e. Name & profile link)? Let's say we want to generate the following HTML in our page through code (“app” div is empty by default).
  1. <div class="mycontainer">  
  2.             <h3>Bilal Shahzad</h3>  
  3.             <a href="https://www.youtube.com/c/LearnInUrdu139">Learn in Urdu Tutorials</a>  
  4.         </div>  
This is what we’ll do,
  1. We’ll create a div element
  2. We’ll create a Name element as child of div
  3. We’ll create a Profile element as child of div
Here is the code snippet to do this,
  1. <body>    
  2.     <div id="app">    
  3.     </div>    
  4.     <script>    
  5.         function MyName(props){    
  6.             return React.createElement('h3',null,props.name);    
  7.         }    
  8.         function ProfileLink(props){    
  9.             var url = props.url;    
  10.             var txt = props.urlText;    
  11.             return React.createElement('a',{href:props.url},txt);    
  12.         }    
  13.             
  14.         //Create name & profile elements    
  15.         var nameComp = React.createElement(MyName, {name:"Bilal Shahzad"});    
  16.         var dataToPass = {url:"https://www.youtube.com/c/LearnInUrdu139",urlText: "Learn in Urdu Tutorials"};    
  17.         var profileComp = React.createElement(ProfileLink, dataToPass);    
  18.     
  19.         //create div element to hold name & profile elements    
  20.         var el = React.createElement(    
  21.             'div'    
  22.             ,{class:'mycontainer'}    
  23.             ,nameComp    
  24.             ,profileComp);    
  25.     
  26.         ReactDOM.render(el,document.getElementById('app'));    
  27.     </script>    
  28. </body>     
Explanation
 
We’ve created name & link elements using relevant components by providing required properties to them. Then we’ve created a parent (div) element using the same React.createElement() function. In this case we’ve provided multiple react elements as children, and yes, we may provide more. Then we’ve added it in DOM. If we run the page, the following should be output & html generated by react.
 
react
 
Now shouldn't we have a profile component which shows one person's profile (name & link)? Let’s convert the newly-created div into a separate component so we can reuse it. Don’t get confused, please check comments in the snippet & the explanation below for better understanding.
  1. <body>    
  2.     <div id="app">    
  3.     </div>    
  4.     <script>    
  5.         function MyName(props){    
  6.             return React.createElement('h3',null,props.name);    
  7.         }    
  8.         function ProfileLink(props){    
  9.             var url = props.url;    
  10.             var txt = props.urlText;    
  11.             return React.createElement('a',{href:props.url},txt);    
  12.         }    
  13.             
  14.         function Profile(props){    
  15.             //Create name & profile elements    
  16.             var nameComp = React.createElement(MyName, props);    
  17.             var profileComp = React.createElement(ProfileLink, props);    
  18.             //create div element to hold name & profile elements    
  19.             var el = React.createElement(    
  20.             'div'    
  21.             ,{class:'mycontainer'}    
  22.             ,nameComp    
  23.             ,profileComp);    
  24.     
  25.             return el;    
  26.         }    
  27.             
  28.         //create object to pass as props    
  29.         var personData = {    
  30.             name : "Bilal Shahzad",     
  31.             url:"https://www.youtube.com/c/LearnInUrdu139",    
  32.             urlText: "Learn in Urdu Tutorials"    
  33.         };    
  34.             
  35.         var el = React.createElement(Profile,personData);    
  36.     
  37.         ReactDOM.render(el,document.getElementById('app'));    
  38.     </script>    
  39. </body>    
Explanation
 
We’ve moved code to create a “div” element in a separate function (component). We are going to pass dynamic content from outside as props. We may pass specific props to name & link components but we’ve provided the same props object to them for our ease. Then we’ve created a single object which contains name, url & urlText. Then we created profile element. Run page & it should be working fine.
 
Now what if we want to show another profile on the page? Simple, we just need to:
  • Create another data object of that profile
  • Create another profile element
  • Wrap both profile elements in some container and add that container in DOM.
Here is the code snippet to show how to do this (Note: No change in components)
  1. //create object to pass as props  
  2.         var personData = {  
  3.             name : "Bilal Shahzad",   
  4.             url:"https://www.youtube.com/c/LearnInUrdu139",  
  5.             urlText: "Learn in Urdu Tutorials"  
  6.         };  
  7.           
  8.         //create profile element  
  9.         var profile1 = React.createElement(Profile,personData);  
  10.   
  11.         //create object to pass as props  
  12.         var personData2 = {  
  13.             name : "Faisal Shahzad",   
  14.             url:"https://www.youtube.com/c/LearnInUrdu139",  
  15.             urlText: "Learn in Urdu Tutorials 2"  
  16.         };  
  17.           
  18.         //create profile element  
  19.         var profile2 = React.createElement(Profile,personData2);  
  20.   
  21.         var el = React.createElement(  
  22.             'div'  
  23.             ,{class:'maincontainer'}  
  24.             ,profile1  
  25.             ,profile2);  
  26.   
  27.         ReactDOM.render(el,document.getElementById('app'));  
Explanation
 
We’ve just used our profile component multiple times. We created 2 profile elements and then added them in a div element as we need a single element to add in DOM. We then added the div element in DOM. If we run the page, the following should be output & html generated by react.
 
react
 
But wait, what? Is this React? Is this creating ease for us or making things difficult? A normal page has many elements, are we going to create components like this? Where are our own tags e.g. <Person>? Yes, you may use this approach (i.e. using React.createElement()) functions or optionally use JSX to ease things.
 

What is JSX?

  • JSX stands for JavaScript XML
  • It is an HTML-like syntax
  • JavaScript & HTML can be mixed
  • It just providesthe  sugar coating of syntax we’ve seen above
Let’s check an example of creating React elements using JSX
  1. function MyName(props){  
  2.             //return React.createElement('h3',{id:'myheader',class:'test'},props.name);  
  3.             return <h3 id='myheader' class='test'>{props.name}</h3>  
  4.         }  
Explanation
 
We can create our elements like we do with HTML. But here we can mix JavaScript by using curly braces (e.g. {props.name}
 
But before we start using it, we need to do a couple of things.
 
Import the following script in head, now there should be three references.
  1. <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>  
  2.     <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>  
  3.     <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>  
Update script tag with the following:
  1. <script type='text/babel'>  
Here is the full snippet which is creating a Name component by using JSX syntax.
  1. <html>    
  2. <head>    
  3.     <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>    
  4.     <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>    
  5.     <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>    
  6. </head>    
  7. <body>    
  8.     <div id="app">    
  9.     </div>    
  10.     
  11.     <script type='text/babel'>    
  12.         //Component is still return react element    
  13.         function MyName(props){    
  14.             return <h3 id='myheader' class='test'>{props.name}</h3>    
  15.         }    
  16.             
  17.         //Created a top level component    
  18.         function MyApp(){    
  19.             return (    
  20.                 //Using our custom tag (component), passing data as properties    
  21.                 <MyName name="Bilal Shahzad"/>    
  22.             );    
  23.         }    
  24.     
  25.         ReactDOM.render(<MyApp />,document.getElementById('app'));    
  26.     </script>    
  27. </body>    
  28.      
  29. </html>     
Explanation
 
We’ve updated MyName() component and now we are returning React element using JSX syntax. We are using HTML & mixing JavaScript by using curly braces. We’ve also created a top level component which will hold our other components. In MyApp() component, we’ve used MyName component as we use HTML tags. Now we are passing properties to component (e.g. name=”Bilal Shahzad”) as we set in HTML. Then we’ve used <MyApp /> syntax in ReactDOM.render() method.
 
Let’s try to convert our Persons example using JSX. It should be something like this.
  1. <html>    
  2. <head>    
  3.     <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>    
  4.     <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>    
  5.     <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>    
  6. </head>    
  7. <body>    
  8.     <div id="app">    
  9.     </div>    
  10.     
  11.     <script type='text/babel'>    
  12.         function MyName(props){    
  13.             return <h3>{props.name}</h3>    
  14.         }    
  15.         function ProfileLink(props){    
  16.             return <a href={props.url}>{props.urlText}</a>;    
  17.         }    
  18.             
  19.         function Profile(props){    
  20.             return (    
  21.                 <div class="mycontainer">    
  22.                     <MyName name={props.name} />    
  23.                     <ProfileLink url={props.url} urlText={props.urlText} />    
  24.                 </div>    
  25.             );    
  26.         }    
  27.             
  28.         //Created a top level component    
  29.         function MyApp(){    
  30.             return (    
  31.                 <div class="maincontainer">    
  32.                     <Profile name="Bilal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials" />    
  33.                     <Profile name="Faisal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials 2" />    
  34.                 </div>    
  35.             );    
  36.         }    
  37.     
  38.         ReactDOM.render(<MyApp />,document.getElementById('app'));    
  39.     </script>    
  40. </body>    
  41.      
  42. </html>     
Explanation
 
We’ve updated MyName, ProfileLink & Profile components with JSX approach. Then we’ve created two profiles in MyApp component. We can see how simplified it has become with JSX. It is more readable now.
 
So we’ve learnt that we can create a React application using 1) React plain code OR 2) Using JSX
 

What is Babel?

 
Babel is a JavaScript compiler (or transpiler) that includes the ability to compile JSX into regular JavaScript. When it is used with React, it converts JSX into React code.
 
To understand it better 
  1. Go to https://babeljs.io/repl. It will show us what it generates against JSX
  2. Copy following JSX code and paste in left panel, it will show generated react code in right panel
  1. var name = "Bilal Shahzad";  
  2. <h3 id="test">{name}</h3>  

Practice Tasks

  1. Create a new array of objects in MyApp and render multiple profiles against it. Hint: You need to use map function to iterate array.
  2. Check what react code is generated against JSX we’ve after Task 1.

Conclusion

 
In this part, we’ve extended our learning of React and learned about “Function Components”. A function component takes properties as input and returns a React element. We learned how JSX eases our work by allowing us to use HTML like syntax with a mixture of JavaScript statements.
 
For more reading on JSX,
 
https://reactjs.org/docs/jsx-in-depth.html