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
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
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
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
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
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.
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
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")
}
Top comments (1)
It's very easy to know