Introduction
What we’ll learn in this part:
Before we proceed any further with React, we need to understand some JavaScript concepts/constructs. I know this article is about React, but a good understanding of these concepts will not make you confused while trying to understand the existing React code. You may skip any section if you are already knowledgable in the concept.
Classes in JavaScript
JavaScript is a functional programming language i.e. everything is a function. If we want to do Object Oriented Programming in it, we still use functions to achieve class-like behavior. Prototypal inheritance exists to achieve OOP inheritance. We’ll not go into more details of it. If you don’t know how this works, don’t worry, this understanding is not required for React.
Before ES6 (ECMAScript2015), the class keyword does exist in JavaScript but just as a reserved keyword. In ES6, classes are introduced. But it is just syntactical sugar coating over existing prototype-based inheritance. It means behind the scenes, no new model is introduced in JavaScript. In short, we can create classes in JS as we do in other OOP languages (e.g. C#, Java). Every new version of ES introduces new features to classes.
In the following example, we are creating a Person class which has three properties (id, name & age). Then we’ve created the ‘Employee’ class which is inheriting the ‘Person’ class. Open a page in your browser and check the output on the console.
- <html>
- <head>
- </head>
- <body>
- <script >
- class Person {
- id =0;
- name;
- constructor(i,n,a){
- this.id = i;
- this.name = n;
- this.age = a;
- }
-
- show(){
- console.log('ID is:' + this.id);
- console.log('Name is:' + this.name);
- console.log('Age is:' + this.age);
- }
-
-
- show2 = function(){
- console.log('valid function');
- }
- }
-
-
- var obj = new Person(1,"Bilal",100);
- obj.show();
- obj.show2();
-
- class Employee extends Person {
- constructor(i,n,a,comp){
- super(i,n,a);
- this.company = comp;
- }
- show(){
- super.show();
- console.log('Company is:' + this.company);
- }
- }
- console.log('--------------------');
- var emp = new Employee(2,"Bilal S",100,'LearningInUrdu.pk');
- emp.show();
- </script>
- </body>
-
- </html>
- We create a class by using the ‘class’ keyword like we do in C# or Java.
- No keyword is required to declare a variable. The ‘function’ keyword can be skipped to declare a function in class.
- The ‘this’ keyword is the same as we’ve seen in other languages. It represents the caller.
- We create an instance of a class by using the ‘new’ keyword as we do in C# or Java.
- A function with the name ‘constructor’ is a special function. Its concept is the same as we’ve in other languages. In JS, we can have only one such function in class.
- Class data members can be declared inside the constructor or outside the constructor. Declaration can be with or without initialization.
- We can have static functions & static data members like we’ve in other languages.
- We can inherit other classes by using extends keyword like we do in Java. If we have a constructor in the child class, its first statement should be called to ‘super()’ function. ‘super()’ function executes parent class constructor.
- To call the function of the parent class, ‘super’ keyword can be used (e.g. super.Show())
Should we start using classes now?
Yes & No. classes are introduced in ES6 so before using classes (or any internal feature e.g. static or private data members), we need to check if a browser supports this feature or not. OR we may use transpilers (e.g. TypeScript or Babel) which allow us to use the latest features and then allow us to convert our code into an older version of ECMAScript if required.
‘this’ operator
“this” inside a function represents a “caller”. If a function is part of an object, we can call that function using dot (.) notation (e.g. myObj.Show()). In this case, “this” inside “Show” function represents (or alias of) “myObj” object. We can use different callers for a function by using ‘call’ or ‘apply’ methods. Flexibility to have different callers of the same function is a powerful feature but sometimes we don’t want this.
- <script >
- var obj ={
- a: 10,
- show: function(){
- alert('value of a is:' + this.a);
- }
- }
-
-
- obj.show();
-
-
- var func = obj.show;
-
- var obj2 = {
- a:20
- }
-
-
-
- func.call(obj2);
-
- </script>
Here is the same example of ‘this’ using classes
- <script >
- class Person{
- a = 10;
- constructor(){
- }
- show(){
- console.log('value of a is:' + this.a);
- }
- }
-
- var obj = new Person();
-
- obj.show();
-
-
- var func = obj.show;
- func();
-
- </script>
Sometimes we want to use a “predefined” object for “this” irrespective of caller. There are multiple ways of doing this. We'll see those in the next article.
React Class Component
We’ve learned about the Function component earlier. Let see how we can create a class component. In the following example, we’ve converted our ‘Profile’ component to the class component. Both approaches are given for learning purposes. Remember ‘React Class Component’ is just a class which we’ve discussed at the start of this article.
- <script type='text/babel'>
-
-
- function Profile(props){
- return (
- <div class="mycontainer" >
- <h3>{props.name}</h3>
- <a href={props.url}>{props.urlText}</a>;
- </div>
- );
- }
-
-
- class Profile extends React.Component{
-
- constructor(pro){
- super(pro);
- }
- render(){
- return (
- <div class="mycontainer" >
- <h3>{this.props.name}</h3>
- <a href={this.props.url}>{this.props.urlText}</a>;
- </div>
- );
- }
- }
-
- </script>
- A class component is a class that is inheriting React.Component class
- In the React instance of our component, it passes ‘props’ to the constructor. We must call super() as the first statement. If we miss this call, we'll get an error. Writing a constructor function is optional.
- React creates 'props' as class member so we can access it by using 'this.props' anywhere.
- We’ve moved our component UI part in the ‘render()’ method. As ‘props’ data is not available in this function but available in class level property, we need to access it using ‘this’.
- Also, it is not required to have all components of one type (e.g. Function component or class component)
In the following example, we’ve converted ‘Profiles’ component using class components. Changes are the same that we have seen while converting the ‘Profile’ component. Both approaches are given for learning purposes.
- <script type='text/babel'>
- function Profiles(props){
- var profilesElem = props.data.map(
- (obj)=>(
- <Profile
- key={obj.id}
- eid={obj.id}
- name={obj.name}
- url={obj.url}
- urlText={obj.urlText}
- />)
- );
- return profilesElem;
- }
-
- class Profiles extends React.Component{
- //We've removed constructor intentionally
- render(){
- var profilesElem = this.props.data.map(
- (obj)=>(
- <Profile
- key={obj.id}
- eid={obj.id}
- name={obj.name}
- url={obj.url}
- urlText={obj.urlText}
- />)
- );
- return profilesElem;
- }
- }
-
- </script>
In following example, we’ve converted MyApp component.
- <script type='text/babel'>
- function MyApp(){
-
-
- var data = [
- {id: 1, name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},
- {id: 2, name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"},
- {id: 3, name:"Waqas Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 3"},
- {id: 4, name:"Khurram Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 4"}
- ];
-
- return (
- <div class="maincontainer">
- <Profiles data={data} />
- </div>
- );
- }
-
- class MyApp extends React.Component{
- data = [
- {id: 1, name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},
- {id: 2, name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"},
- {id: 3, name:"Waqas Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 3"},
- {id: 4, name:"Khurram Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 4"}
- ];
-
- render(){
- return (
- <div class="maincontainer">
- <Profiles data={this.data} />
- </div>
- );
- }
- }
- </script>
Here is a full example with class components. Note that the event handling code is removed intentionally to keep things simpler.
- <script type='text/babel'>
- class Profile extends React.Component{
- constructor(pro){
- super(pro);
- }
- render(){
- return (
- <div class="mycontainer" >
- <h3>{this.props.name}</h3>
- <a href={this.props.url}>{this.props.urlText}</a>;
- </div>
- );
- }
- }
-
- class Profiles extends React.Component{
-
- render(){
- var profilesElem = this.props.data.map(
- (obj)=>(
- <Profile
- key={obj.id}
- eid={obj.id}
- name={obj.name}
- url={obj.url}
- urlText={obj.urlText}
- />)
- );
- return profilesElem;
- }
- }
-
-
- class MyApp extends React.Component{
- data = [
- {id: 1, name:"Bilal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials"},
- {id: 2, name:"Faisal Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 2"},
- {id: 3, name:"Waqas Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 3"},
- {id: 4, name:"Khurram Shahzad",url:"https://www.youtube.com/c/LearnInUrdu139",urlText:"Learn in Urdu Tutorials 4"}
- ];
-
- render(){
- return (
- <div class="maincontainer">
- <Profiles data={this.data} />
- </div>
- );
- }
- }
-
- ReactDOM.render(<MyApp />,document.getElementById('app'));
- </script>
Now let’s add some buttons to ‘Profile’ component and show an alert when button is clicked. We’ll notice that first two buttons will be throwing exception on console but third button click is working fine. Can you guess? We’ll check this in next article as it requires more understanding of the 'this' operator.
- <script type='text/babel'>
- class Profile extends React.Component{
-
- CountClickHandler(e){
-
- alert(this.props.eid);
- }
- render(){
- return (
- <div class="mycontainer" >
- <h3>{this.props.name}</h3>
- <a href={this.props.url}>{this.props.urlText}</a>
- <button onClick={function(){alert(this.props.eid);}} >Count Me In 1</button>
- <button onClick={this.CountClickHandler} >Count Me In 2</button>
- <button onClick={()=> {this.CountClickHandler()}} >Count Me In 3</button>
- </div>
- );
- }
- }
- </script>
If you have any questions or suggestions to improve this article, don't hestiate to share.
Summary
We basically learned another type of component i.e. class components. Both types of components receive 'props'. To understand it in a better way, we learned about classes in JavaScript.
Links for more reading:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
- https://hacks.mozilla.org/2015/07/es6-in-depth-classes/