React - Learn From Scratch - Part Three

What we’ll learn in this part:
  • More on JSX
  • What is arrow function in JavaScript
  • What is map function
  • Using map function to iterate data in JSX
  • Part One
  • Part Two

More on JSX

 
Let’s learn more about JSX as this will help us in fixing most common issues while working with React/JSX.
 
JSX is:
  • HTML like syntax in which you can write JavaScript expressions in curly braces.
  • OR JavaScript code in which you can use HTML like tags.
With JSX, when we are writing HTML & want to write some JavaScript within it, we need to use curly braces {}. We can’t have multiple statements in this. So can we use a “for” loop or if statement in these curly braces? The answer is "No". If we need to have complex logic which requires multiple statements (or curly braces), we should create a separate function and then call that function in JSX curly braces or prepare final result separately and place that in curly braces.
 
User defined components must be capitalized.
 
When we start element with lower case, React refers to built-in tags (e.g. div, h1).
 
For example, in following code “MyName” is started with lowercase (“myName”) so React will think that it is HTML tag.
  1. <script type='text/babel'>  
  2.         function MyName(props){  
  3.             return <h3>{props.name}</h3>  
  4.         }  
  5.           
  6.         //Created a top level component  
  7.         function MyApp(){  
  8.             return (  
  9.                 <div class="maincontainer">  
  10.                     {/*Correct*/ }  
  11.                     <MyName name="Bilal Shahzad 1" />  
  12.   
  13.                     {/*will give error*/ }  
  14.                     <myName name="Bilal Shahzad 2" />  
  15.                 </div>  
  16.             );  
  17.         }  
  18.   
  19.         ReactDOM.render(<MyApp />,document.getElementById('app'));  
  20.     </script>  
If we check on the console, we’ll see the following error:
 
 
Assume these tags are objects and yes they are, i.e., React Elements.
 
If these tags are objects, can we store them in some variable? Can we add them in an array? Can we pass them to a function? Can we return them from a function? Yes, we can.
  1. function MyApp(){  
  2.               
  3.             var o = <Profile name="Bilal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials" />  
  4.             console.log(o);  
  5.   
  6.             return o;  
  7.         }  
If we check output on console, we can see that it is a React element which contains ‘props’ property in it.
 
 
 
Here is another example
  1. function MyApp(){  
  2.            var h = <h3>Profiles</h3>  
  3.            console.log(h);  
  4.            var o = <Profile name="Bilal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials" />  
  5.            var o1 = <Profile name="Faisal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials 2" />  
  6.   
  7.            return [h,o,o1];  
  8.        }  
And here is output on console, Note: we’ve used HTML tag (h3) and we can see it is also a React element which will produce h3 tag in browser.
 
 
Note
When we want to return multiple elements from our component without a parent, we can return array element as used above. Here is another example.
  1. function MyApp(){  
  2.             var h = <h3>Profiles</h3>  
  3.   
  4.             //returning multiple elements without parent  
  5.             return (  
  6.                 [  
  7.                 h,  
  8.             <Profile name="Bilal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials" />,  
  9.             <Profile name="Faisal Shahzad" url="https://www.youtube.com/c/LearnInUrdu139" urlText="Learn in Urdu Tutorials 2" />  
  10.                 ]);  
  11.         }  
Let’s update our MyApp component and render different profiles programmatically.
 
Let’s assume we have data as an array of objects. We want to generate Profiles based on this data. We need to iterate this array and generate Profile components. But we can’t use for loop in JSX curly braces so we’ve prepared our result separately and then just placed that in curly braces to render it.
  1. <script type='text/babel'>  
  2.         function MyName(props){  
  3.             return <h3>{props.name}</h3>  
  4.         }  
  5.         function ProfileLink(props){  
  6.             return <a href={props.url}>{props.urlText}</a>;  
  7.         }  
  8.           
  9.         function Profile(props){  
  10.             return (  
  11.                 <div class="mycontainer">  
  12.                     <MyName name={props.name} />  
  13.                     <ProfileLink url={props.url} urlText={props.urlText} />  
  14.                 </div>  
  15.             );  
  16.         }  
  17.          
  18.         //Created a top level component  
  19.         function MyApp(){  
  20.               
  21.             //hard coded data for now  
  22.             var data = [  
  23.                 {name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},  
  24.                 {name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"}  
  25.                 ];  
  26.               
  27.             //create an array to hold profile objects  
  28.             var result = [];  
  29.             for(var i=0;i<data.length;i++){  
  30.                 var obj = data[i];  
  31.                 result.push(<Profile name={obj.name} url={obj.url} urlText={obj.urlText} />)  
  32.             }  
  33.   
  34.             return (  
  35.                 <div class="maincontainer">  
  36.                     {result}  
  37.                 </div>  
  38.             );  
  39.         }  
  40.   
  41.         ReactDOM.render(<MyApp />,document.getElementById('app'));  
  42.     </script>  
Let’s update the above code & create another component, Profiles, to hold this logic. We are passing ‘data’ object in props.
  1. <script type='text/babel'>  
  2.         function MyName(props){  
  3.             return <h3>{props.name}</h3>  
  4.         }  
  5.         function ProfileLink(props){  
  6.             return <a href={props.url}>{props.urlText}</a>;  
  7.         }  
  8.           
  9.         function Profile(props){  
  10.             return (  
  11.                 <div class="mycontainer">  
  12.                     <MyName name={props.name} />  
  13.                     <ProfileLink url={props.url} urlText={props.urlText} />  
  14.                 </div>  
  15.             );  
  16.         }  
  17.   
  18.         function Profiles(props){  
  19.             var data = props.data;  
  20.             //create an array to hold profile objects  
  21.             var result = [];  
  22.             for(var i=0;i<data.length;i++){  
  23.                 var obj = data[i];  
  24.                 result.push(<Profile name={obj.name} url={obj.url} urlText={obj.urlText} />)  
  25.             }  
  26.             return result;  
  27.         }  
  28.          
  29.         //Created a top level component  
  30.         function MyApp(){  
  31.               
  32.             //hard coded data for now  
  33.             var data = [  
  34.                 {name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},  
  35.                 {name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"}  
  36.                 ];  
  37.               
  38.             return (  
  39.                 <div class="maincontainer">  
  40.                     <Profiles data={data} />  
  41.                 </div>  
  42.             );  
  43.         }  
  44.   
  45.         ReactDOM.render(<MyApp />,document.getElementById('app'));  
  46.     </script>  
Can we achieve above funtionality with less code? Let's learn a couple of concepts before that. 
 

Arrow functions in JavaScript

 
Arrow function is a new style to write anonymous function in JavaScript. This syntax was introduced in ES6 (ECMAScript 2015). Some important points regarding arrow functions are,
  • No ‘function’ keyword is used.
  • Parentheses are used to declare parameters.
  • Arrow operator (=>) is used to indicate function body.
  • Curly braces of body can be skipped if function has only one statement. If function has only one statement, no need to use ‘return’ statement.
  • Curly braces can be used if there are multiple statements and ‘return’ will have to be used explicitly if function is going to return something.
Here are some examples of how we can create arrow functions.
  1. <script>  
  2.   
  3.         var f1 = () => console.log('Arrow function without body');  
  4.           
  5.         var f2 = () => {  
  6.             console.log('Arrow function with body');  
  7.         }  
  8.   
  9.         //Arrow function which is taking input parameters & returning their sum  
  10.         var f3 = (a,b) => a+b;  
  11.   
  12.         f3(5,10);  
  13.   
  14.         //Arrow function which is taking input parameter & returning their sum  
  15.         var f4 = (a,b) => {  
  16.             return a+ b;  
  17.         }  
  18.   
  19.         f4(15,20);  
  20.   
  21.         //Arrow function which is taking single input parameter, parenthesis can be skipped  
  22.         //Following function 'f5' is taking a paramter and returning by multiplying to 5.  
  23.           
  24.         var f5 = a => a*5;  
  25.       
  26.         /* Non-Arrow version of above function 
  27.         var f5 = function(a){ 
  28.             return a*5; 
  29.         } 
  30.         */  
  31.   
  32.     </script>  

Array map() function

 
Map function takes a (callback) function as input parameter and executes that function for every element of the array. It prepares a new array based on the returned values.
  1. <script>  
  2. function Test(value,index,Arr){              
  3.             return 'v is ' + value;  
  4.         }  
  5.         var arr = [1,2,3,4];  
  6.         var res = arr.map(Test)  
  7.         console.log(res);  
  8.         //output will be Array: ["v is 1", "v is 2", "v is 3", "v is 4"]  
  9. <script>  
Here is another example using Anonymous function:
  1. <script>  
  2.         //Using Anonymous Function  
  3.         var arr = [1,2,3,4];  
  4.         var res = arr.map(function(value,index,Arr){              
  5.             return 'v is ' + value;  
  6.         });  
  7.         console.log(res);  
  8.         //output will be Array: ["v is 1", "v is 2", "v is 3", "v is 4"]  
  9.     </script>  
Another example
  1. <script>  
  2.         var arr = [1,2,3,4];  
  3.         var res = arr.map(function(value,index,Arr){              
  4.             if(value%2 == 0)  
  5.                 return 'even';  
  6.             else  
  7.                 return 'odd';  
  8.         });  
  9.         console.log(res);  
  10.         //output will be Array: ["odd", "even", "odd", "even"]  
  11.     </script>  
Note
map function should not be used if
  • We are not using the array it returns
  • OR We are not returning anything from callback function
Instead we should use forEach.
  
Now let’s update our React example but using arrow function syntax and JavaScript map function to clean our code (and yes, it becomes less readable if we don't have a  good understanding of these concepts).
  1. <script type='text/babel'>  
  2.         function MyName(props){  
  3.             return <h3>{props.name}</h3>  
  4.         }  
  5.         function ProfileLink(props){  
  6.             return <a href={props.url}>{props.urlText}</a>;  
  7.         }  
  8.           
  9.         function Profile(props){  
  10.             return (  
  11.                 <div class="mycontainer">  
  12.                     <MyName name={props.name} />  
  13.                     <ProfileLink url={props.url} urlText={props.urlText} />  
  14.                 </div>  
  15.             );  
  16.         }  
  17.   
  18.         function Profiles(props){  
  19.             //Note we hadn't used {} as function body but used () to show body of arrow function  
  20.             return props.data.map((obj)=>(<Profile name={obj.name} url={obj.url} urlText={obj.urlText} />));  
  21.         }  
  22.          
  23.         //Created a top level component  
  24.         function MyApp(){  
  25.               
  26.             //hard coded data for now  
  27.             var data = [  
  28.                 {name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},  
  29.                 {name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"},  
  30.                 {name:"Waqas Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 3"},  
  31.                 {name:"Khurram Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 4"}  
  32.                 ];  
  33.               
  34.             return (  
  35.                 <div class="maincontainer">  
  36.                     <Profiles data={data} />  
  37.                 </div>  
  38.             );  
  39.         }  
  40.   
  41.         ReactDOM.render(<MyApp />,document.getElementById('app'));  
  42.     </script>  
In the next part, we’ll learn how we do event handling in React.
 

Summary

 
We learnt more about JSX and then we learnt map & arrow functions as those are extensively used while working with React.
 
For more details,
  • https://reactjs.org/docs/jsx-in-depth.html
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions