Day 2 : React start for Beginner - Component (Class)
Tags: class, javascript, react
Published: 2022-05-24 18:00:07

---
title: Day 2 : React start for Beginner - Component (Class)
published: true
description: React Class Component
tags: class, javascript, react
//cover_image: https://direct_url_to_image.jpg
---

Create react project `create-react-app counter-app` run the command space and provide your application name. So this command creates the react application. And automatically set up the necessary development server babel and web pack. The development server helps us to execute react applications after compilation. 

### Setting Up the Project (Install Bootstrap)
`npm i bootstrap@4.1.1`

Import **index.js** file
`import 'bootstrap/dist/css/bootstrap.css';`

Into the **src** folder create a **components** folder. And add a new file, we call it **counter.jsx**. Note that here I'm using camel notation. So the first letter of the first word should be lower case. 

### Your First React Component
```
import React, { Component } from 'react';

class Counter extends Component {
    state = {

    };
    render() {         
        return ()
     }
}
```
Initially **Counter** component showing like that.  

```
render() {         
        return <h1>Hello World</h1>
     }
```
It's a **JSX** expression. It's not a string

Import **counter component** into **index.js** file
`import Counters from './components/counters';`
> Counter is default export, we don't need curly braces around it.

And finally where we are rendering a React component. Instead of the app component, we're going render our **Counter Component**

```
ReactDOM.render(
  <Counters />,
  document.getElementById('root')
);
```
### Embedding Expressions
We need to add property, call it state and set it to an object. State is a special property in React component, and basically it's an object that includes any data that is component needs. 

```
state = {
        count: 0,
    };
```
Now, I'm going to replace with a span. 
So if you want to render the value of the count property here. You would write code like this. This, reference the current object

```
class Counter extends Component {
    state = {
      count: 0
    };
    render() {         
        return (
           <span>{this.state.count} </span>
         )
     }
}

```
In between these curly braces we can write any valid JavaScript expressions. An expression is something that produces value. For example, we can write something like `2+2`

Now update few things. We can call the function that returns a value. For example let's add a method in this calls it format count. 
```
formatCount(){
        // object destructuring
        const { count } = this.state;
        return count === 0 ? 'Zero' : count;
        // return count === 0 ? <h2>Zero</h2> : count; // jsx expression support also
    }
```

```
<span>{this.formatCount()}</span>
```
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a5k95ggyg4zzi1x29qu.png)

### Setting Attributes
How to set in these element. Let's add this image here. 

```
<img src="" alt="" />
```
To set the value of the source attribute dynamically. So add property in state object. 

```
state = {
        count: 0,
        imageUrl: 'https://picsum.photos/200'
    };
```
Generate a random 200x200 pixel image. Now back to the image element. Let's replace the quotes with braces. That we can use these braces to render values dynamically. 

```
<img src={this.state.imageUrl} alt="" />
```
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppekcj4p99d6tutifko1.png)
#### class attributes 
We want to apply a class to this span element, the name of the attribute is not class, it's class name. 

```
<span  className="badge badge-primary m-2">{this.formatCount()}
//<span  className={this.getBadgeClasses()}>{this.formatCount()}</span>
```
We cannot use **class** property on an object, because that's a reserve keyword in JavaScript. So name of the **attribute** in JSX is **className**. Use a couple of bootstrap classes, one is **badge badge-primary**

#### Rendering class dynamically
Out badge is currently blue, but let's change this application such that if the value of count property is 0, we want to render this as yellow, to indicate this some kind of warning, otherwise we want to render it as blue. 
```
    getBadgeClasses() {
        let classes = "badge m-2 badge-";
        classes += this.state.count === 0 ? "warning" : "primary";
        return classes;
    }
```
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bntl6dmo165k42d42zxq.png)

#### style attributes 
In JSX, we have this **style** attribute that we need to set to a plan JavaScript object. So first we need to   add curly braces here, now in between these curly braces we need to pass a plain JavaScript object. Here one way to do this. 

```
    styles = {
        fontSize: 40,
        fontWeight: "bold"
    }
```
```
<span style={this.styles}  className={this.getBadgeClasses()}>{this.formatCount()}</span>
```
#### another way
```
<span style={{fontSize: 30}}  className={this.getBadgeClasses()}>{this.formatCount()}</span>
```
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcy45dix67kbcbyyqvkl.png)

### Rendering List
Tags, we set in to an array of three strings tag1, tag2, tag3

```
   state = {
        count: 0,
        imageUrl: 'https://picsum.photos/200',
        tags: ['tag 1', 'tag 2', 'tag 3']
    };
```
Now here in our render method, we want to render these tags using ul, and li elements. 

Now if you have worked with Angular, you have seen the **ngFor** directive, we use that to implement a loop in our templates. 
But in React, in JSX expressions, we don't have the concept of loops, because JSX is really not a template engine, it's just simple syntax that will eventually get compiled to react element. So how can we render a bunch of tags here. 

We can use the map method. Render something dynamically, so we start with curly braces. We get `this.state.tags` this is an array, so here have a map method. Now as the **argument** we need to pass an arrow function, **tag** goes to now we get each tag and map it to a list item. 

```
<ul>
    {this.state.tags.map((tag) => <li>{tag}</li>)} 
</ul>
```
So this is how we render a list of items in React. 
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzu3gjvos78dvv1jqcae.png)
In the console, we should see this error. Each child in an array or iterator should have a unique key. Because it needs to uniquely identify. React element in the virtual DOM changes, react wants to quickly figure out what element is changed, and where in the DOM it should make changes to keep the DOM in sync with the virtual DOM.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo2nj7vq0dt3y4egmdln.png)
 
So whenever you're using the map method to render a list of items, you need to set a **key attribute**. So key, we set this to a dynamic value. 
```
<ul>
   {this.state.tags.map((tag) => <li key={tag}>{tag}</li>)} 
</ul>
```
### Conditional Rendering
We have an array of items and we're rendering that in a list. Now here's a list. 

New requirement, If this array has at least one element, you want to render that array, in a list, otherwise we want to display a message like `there are no tags`. How can we implement this? 

```
<ul>
    {this.state.tags.map((tag) => <li key={tag}>{tag}</li>)} 
</ul>
```
So render elements conditionally. Here's on way to implement the scenario. We can add a separate helper method like **renderTags** 

```
renderTags(){
if(this.state.tags.length === 0) return <p>There are no tags!</p>;
return <ul>{this.state.tags.map(tag => <li key={tag}>{tag}</li>)}</ul>
 }
``` 
```
{this.state.tags.length === 0 && "Please create a new tag"}
{this.renderTags()} 
```

### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4z15hm0f773q8esilmz.png)
### Handling Events
Let's see how we can handle events. So all these React element have property that are based on standard DOM events. For example, here on a button we have a property **onClick**. We also have onDoubleClick, if you're working with input fields you have **onKey onKeypress onKeyUp** all those standard DOM events that you're familiar with. 

Here let's handle the **onClick** event. We set this curly braces because we need to pass an expression. Now the way we do this is by defining a method here. 

```
<button onClick={ this.handleIncrement } className="btn btn-secondary btn-sm">+</button>
```
> Note that the name of the event here is case sensitive. So if you use lower case **c** here you're going to get an error.

```
    handleIncrement = (product) => {
        console.log("Increment Clicked")
    }
```
### Output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqhbj5d1ysgzxidr7a7a.png)

### Reference 
[Day 1 : React start for Beginner](https://dev.to/bipon68/day-1-react-start-for-beginner-56lb)