I already have discussed about React JS in my previous posts. Today, lets see advanced way of using React JS, webpack and ES6 with Node.js to build and run your application. Let’s see what webpack and ES6 does. ES6 (ECMAScript6) is the latest version of javascript that has number of new features to write your javascript code easily. Webpack is mainly designed for larger applications to build the application. The main idea behind webpack/ES6 is code splitting. It allows you to write Javascript as a modularized code, so that you can re-use and share the code to maintain your project over-time.
Download Script Live Demo
This ReactJS application will explain you, how to get search results from Youtube API.
Install NodeJS
You need node.js to create a development server, download and install the latest version. Update NPM
NPM(Node Package Manager) using this you can install different types of JavaScript packages. Go to command/terminal and execute the following command.
$npm update
Note: Linux and Mac users use sudo for user root permissions.
Step 1
Download development application react-webpack.zip or GIT
Extract it you will find the following file stucture.
Step 2
This will install all of the dependent packages like react, react-dom etc..
$npm run install
Step 3
Now install webpack in node root level.
$npm install webpack -g
Here -g refers to globally. This will not support Windows 32 bit OS. Step 4
Now go project directory and execute npm run build. This will compile SASS and ES6 JavaScript code.
$cd react-webpack
$npm run build
$npm run build
Successful Build
Error inBuild
If you make any mistakes, webpack build show you in following way.
Step 5
Open new console/terminal tab, run the following command.
$cd react-webpack
$npm start
$npm start
You can execute the project at http://localhost:8080/
If you have any problem with default port 8080, change the port value in react-webpack/app.js
const port = (process.env.PORT || 8080) //Change the value 8080 to 9000
Output will be "Change here"
Building Youtube Instant Seach
app.js
We are going to modify src/components/app.js project main component.
import React from 'react'
export default class App extends React.Component {
render () {
return (
<div>
<h1>New Code Here</h1>
</div>
)
}
}
export default class App extends React.Component {
render () {
return (
<div>
<h1>New Code Here</h1>
</div>
)
}
}
I am planning to build this application with Bootstrap CSS components for responsive design.
Install Bootstrap SASS
Execute the foll
$cd react-webpack
$npm install bootstrap-sass --save
$npm install bootstrap-sass --save
package.json
After installation you will find the boostrap-sass library in package.json dependencies list. NodeJs will take care your project dependency packages.
"dependencies": {
"bootstrap-sass": "^3.3.7",
"express": "^4.13.4",
"react": "^0.14.8",
"react-dom": "^0.14.8"
}
"bootstrap-sass": "^3.3.7",
"express": "^4.13.4",
"react": "^0.14.8",
"react-dom": "^0.14.8"
}
Using Bootstrap Components
app.scss
Open src/styles/app.scss file and use following code. I will explain more about SASS in my upcoming articles.
$icon-font-path: '~bootstrap-sass/assets/fonts/bootstrap/';
@import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
$project_Fonts: Helvetica, sans-serif;
$project_MainColor: #333333;
body{
font-family: $project_Fonts;
color: $project_MainColor ;
}
@import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
$project_Fonts: Helvetica, sans-serif;
$project_MainColor: #333333;
body{
font-family: $project_Fonts;
color: $project_MainColor ;
}
Bootstrap Template
app.js
Now modify application main component with Bootstrap Template src/components/app.js. Make sure replace class attribute with className, it is a ReactJS standard.
import React from 'react'
export default class App extends React.Component{
render () {
return (
<div className="container">
<div className="row">
<div className="col-md-12">
<h1>ReactJS Youtube Instant Search</h1>
</div>
</div>
Search Input + Results
</div>
)
}
}
export default class App extends React.Component{
render () {
return (
<div className="container">
<div className="row">
<div className="col-md-12">
<h1>ReactJS Youtube Instant Search</h1>
</div>
</div>
Search Input + Results
</div>
)
}
}
Do npm run build for output.
youtubeSearch.js
Main advantage for the ES6 is you can create multiple components. Create a new component at scr/components/youtubeSearch.js
import React from 'react'
import ReactDOM from 'react-dom'
export default class YoutubeSearch extends React.Component {
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput" />
</div>
</div>
Search results
</div>
)
}
}
import ReactDOM from 'react-dom'
export default class YoutubeSearch extends React.Component {
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput" />
</div>
</div>
Search results
</div>
)
}
}
Above code imported react and react-dom libraries. Using componentDidMount focusing the HTML DOM input with ReactDOM.findDOMNode, for more information read Social Network System with React JS
Import component
Open src/components/app.js and import youtubeSearch component in following way. Do npm run build for output.
import React from 'react'
import YoutubeSearch from './youtubeSearch'
export default class App extends React.Component {
render () {
return (
<div className="container">
<div className="row">
<div className="col-md-12">
<h1>ReactJS Youtube Instant Search</h1>
</div>
</div>
<YoutubeSearch/>
</div>
)
}
}
import YoutubeSearch from './youtubeSearch'
export default class App extends React.Component {
render () {
return (
<div className="container">
<div className="row">
<div className="col-md-12">
<h1>ReactJS Youtube Instant Search</h1>
</div>
</div>
<YoutubeSearch/>
</div>
)
}
}
Search Ajax Implementation
youtubeSearch.js
Implement onKeyUp action to trigger searchAction function
import React from 'react'
import ReactDOM from 'react-dom'
export default class YoutubeSearch extends React.Component {
searchAction = (evt) => {
console.log("Getting Results");
}
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput"
onKeyUp={this.searchAction} />
</div>
</div>
Search results part
</div>
)
}
}
import ReactDOM from 'react-dom'
export default class YoutubeSearch extends React.Component {
searchAction = (evt) => {
console.log("Getting Results");
}
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput"
onKeyUp={this.searchAction} />
</div>
</div>
Search results part
</div>
)
}
}
Now Install xhr (XMLHttpRequest) package for ajax features.
npm install xhr --save
package.json
Deployment node severs will taka care your new added dependencies.
"dependencies": {
"bootstrap-sass": "^3.3.7",
"express": "^4.13.4",
"react": "^0.14.8",
"react-dom": "^0.14.8",
"xhr": "^2.2.2"
},
"bootstrap-sass": "^3.3.7",
"express": "^4.13.4",
"react": "^0.14.8",
"react-dom": "^0.14.8",
"xhr": "^2.2.2"
},
youtubeSearch.js
Imported xhr library in header, connecting to Google Youtube APIs for search results.
import React from 'react'
import ReactDOM from 'react-dom'
import xhr from 'xhr'
export default class YoutubeSearch extends React.Component {
state = {
data: []
};
searchAction = (evt) => {
var finalSearchKey = encodeURIComponent(evt.target.value);
var urlAPI = 'https://www.googleapis.com/youtube/v3/search?q=';
var urlKey = '&key=YouTube_Key&maxResults=18&part=snippet';
var url = urlAPI + finalSearchKey + urlKey;
var reactThis=this;
if(finalSearchKey.length>1)
{
xhr({
url: url
}, function (err, data) {
var finalData=JSON.parse(data.body);
reactThis.setState({data: finalData.items})
});
}
};
//Other Code
......
......
......
}
import ReactDOM from 'react-dom'
import xhr from 'xhr'
export default class YoutubeSearch extends React.Component {
state = {
data: []
};
searchAction = (evt) => {
var finalSearchKey = encodeURIComponent(evt.target.value);
var urlAPI = 'https://www.googleapis.com/youtube/v3/search?q=';
var urlKey = '&key=YouTube_Key&maxResults=18&part=snippet';
var url = urlAPI + finalSearchKey + urlKey;
var reactThis=this;
if(finalSearchKey.length>1)
{
xhr({
url: url
}, function (err, data) {
var finalData=JSON.parse(data.body);
reactThis.setState({data: finalData.items})
});
}
};
//Other Code
......
......
......
}
Create Youtube Key
Go to Google API Console enable Youtube APIs for your Google project. Click here you will find more information
Go to Credentials Menu
Create Credentials with HTTP referrers
Add your domains and use the API key.
youtubeResults.js
Displaying Youtube API results component, fetching and parsing JSON data from this.props.data data attribute.
import React from 'react'
export default class YoutubeResults extends React.Component {
render () {
var searchResults=this.props.data.map(function(searchResult, index)
{
return(
<div className="col-md-4">
<div className="videoGrid">
<iframe frameborder="0" height="250"
src={"//www.youtube.com/embed/" + searchResult.id.videoId}
width="100%"></iframe>
</div>
</div>
)
}, this);
return (
<div className="row resultsGrid">
{searchResults}
</div>
)
}
}
export default class YoutubeResults extends React.Component {
render () {
var searchResults=this.props.data.map(function(searchResult, index)
{
return(
<div className="col-md-4">
<div className="videoGrid">
<iframe frameborder="0" height="250"
src={"//www.youtube.com/embed/" + searchResult.id.videoId}
width="100%"></iframe>
</div>
</div>
)
}, this);
return (
<div className="row resultsGrid">
{searchResults}
</div>
)
}
}
youtubeSearch.js
Import YoutubeResuts component inside youtubSearch. API response state dataset assigned to <YoutubeResults data={this.state.data}/>
import React from 'react'
import ReactDOM from 'react-dom'
import xhr from 'xhr'
import YoutubeResults from './youtubeResults'
export default class YoutubeSearch extends React.Component {
state = {
data: []
};
searchAction = (evt) => {
var finalSearchKey = encodeURIComponent(evt.target.value);
var urlAPI = 'https://www.googleapis.com/youtube/v3/search?q=';
var urlKey = '&key=YouTube_Key&maxResults=18&part=snippet';
var url = urlAPI + finalSearchKey + urlKey;
var reactThis=this;
if(finalSearchKey.length>1)
{
xhr({
url: url
}, function (err, data) {
var finalData=JSON.parse(data.body);
reactThis.setState({data: finalData.items})
});
}
};
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput"
onKeyUp={this.searchAction} />
</div>
</div>
<YoutubeResults data={this.state.data}/>
</div>
)
}
}
import ReactDOM from 'react-dom'
import xhr from 'xhr'
import YoutubeResults from './youtubeResults'
export default class YoutubeSearch extends React.Component {
state = {
data: []
};
searchAction = (evt) => {
var finalSearchKey = encodeURIComponent(evt.target.value);
var urlAPI = 'https://www.googleapis.com/youtube/v3/search?q=';
var urlKey = '&key=YouTube_Key&maxResults=18&part=snippet';
var url = urlAPI + finalSearchKey + urlKey;
var reactThis=this;
if(finalSearchKey.length>1)
{
xhr({
url: url
}, function (err, data) {
var finalData=JSON.parse(data.body);
reactThis.setState({data: finalData.items})
});
}
};
componentDidMount() {
ReactDOM.findDOMNode(this.refs.searchInput).focus();
}
render () {
return (
<div className="row">
<div className="col-md-12">
<div className="form-group">
<input type="text" className="form-control" id="searchKey"
placeholder="Search here" ref="searchInput"
onKeyUp={this.searchAction} />
</div>
</div>
<YoutubeResults data={this.state.data}/>
</div>
)
}
}
Final File Structure
Heroku Deployment
Create a Heroku Application
Go to Heroku.com signup and create a free application.
Now click on Deploy link on menu.
Deployment Method
Now connect with Dropbox, you can use other options as well.
App connected to Dropbox
This will create a folder in your Dropbox folder. Apps/Heroku/yourapplicationname
Copy all of your development project files into Dropbox yourapplicationname folder, except node_modules folder.
Now deploy your changes, Heroku build your project based on your project package.json
You can view your project at https://yourapplicationname.herokuapps.com
Domain Redirection
Go to settings options and connect with your custom domain by ading CNAME record.
Nice sharing. This is really an excellent article. I like your blog very much. You are really a superstar in this blogging sector and a pioneer in Indian blogging industry. Thank you sir for staying with us.
ReplyDeleteI agree
DeleteI agree
DeleteEasy to Understand... your screenshots helps me alot thanks
ReplyDeleteWow great tutorial and easy to understand
ReplyDeleteThis tutorial is best. i learn from it
ReplyDeleteThanks for the awesome tutorial, I was searching for this query on Google and your website names comes up, really its a worth opening post. Thanks for the sharing.
ReplyDelete