React series, On the first article we went through react basics and some react syntax, now i want to demonstrate a sample application with es6 syntax. ES6 is the future of javascript, so we use ES6 in our projects. Complete code is available on github, you can use below links.
Example Application
React – Rails Store Example Application
[caption id="attachment_182" align="aligncenter" width="800"] React Rails Store Application[/caption] Before we start, we must familiarize with gulp and some gulp tasks. Gulp is a frontend tool to automate our tasks like sass/scss to css, coffeescript to javascript, minimization etc.. In this project we use babelify, it help us to write code in ES6, In ES6 mode, we can use import statement, classes in javascript, and double arrow functions.var gulp = require('gulp') var fs = require("fs") var browserify = require("browserify") var babelify = require("babelify") var gutil = require('gulp-util'); var source = require('vinyl-source-stream'); var livereload = require('gulp-livereload'); gulp.task("react",function(){ return browserify({ entries:'./app/assets/javascripts/react/main.js', debug: true }) .transform("babelify",{presets:["react","es2015","stage-0"],plugins:["transform-es2015-arrow-functions"]}) .bundle() .pipe(source("bundle.js")) .pipe(gulp.dest("./app/assets/javascripts")) .pipe(livereload()) }) gulp.task("watch",["react"],function(){ livereload.listen({basePath:'public'}) gulp.watch("./app/assets/javascripts/react/*/*.js",["react"]) }) gulp.task("default",["watch"])
We use ES6, so we can use `class`, `import` and `=>`Now we can start our code, It is actually a ruby on rails project. Our files are inside javascript/react folder, we use main.js file where we import all other javascript modules, which again convert to bundle.js then we included it on application.js file. Our main file is main.js , You can find code which use to inject our React components to actual DOM, ReactDOM.render method used to put react component ( first argument) to a DOM element ( Second argument, which is a selector)
import React from 'react'; import ReactDom from "react-dom"; import Sidebar from "./components/sidebar"; import TopSearch from "./components/top-header"; import ProductGallery from "./components/product/product-gallery"; import Pagination from "./components/pagination"; ReactDom.render( <Sidebar />, document.getElementById('sidebar-elements')) ReactDom.render(<TopSearch />, document.getElementById('top-search-bar')) /** * Some section are specific to some pages, so first check that those section are * available to current page , equalent to jquery `element.length` * */ var productSectionElement = document.querySelectorAll('#product-section'); if(productSectionElement.length > 0){ ReactDom.render(<ProductGallery/>, document.getElementById('product-section')) } var paginationElement = document.querySelectorAll('#pagination'); if(paginationElement.length > 0){ ReactDom.render(<Pagination/>, document.getElementById('pagination')) }
With ES6 we can import modulesReactDom.render function used to push components to inside DOM elements, In this , Sidebar component pushed to an element with id ‘sidebar-element’. You can refer sidebar.html.erb ( which is a partial called in layout.erb and reside inside common folder under view)
<div id="sidebar-elements"></div>This sidebar component defined in component folder under react ( ‘react-with-rails/app/assets/javascripts/react’)
import React from "react"; import ATag from './html_components' class Sidebar extends React.Component{ constructor(){ super() this.state = { active: false } } render(){ return( <div className="sidebar"> <div className="vertical menu"> <SidebarLinks href="#" name="Motorola"/> <SidebarLinks href="#" name="Sony"/> <SidebarLinks href="#" name="Lenovo"/> <SidebarLinks href="#" name="Asus"/> <SidebarLinks href="#" name="Dell"/> </div> </div> ) } } class SidebarLinks extends React.Component{ constructor(){ super() } render(){ return( <li> <ATag href={this.props.href} name={this.props.name}/> </li> ) } } export default Sidebar;Above code is used to make Sidebar component, We can see that one Component called another Component ( <SidebarLinks/>) which also called another one ( <ATag/>). This is Parent – Child components, One Parent can call as many child elements. This is one advantage, We can make re usable components. State and Props are two properties used to control a component, State is its own property, and Props is a property coming from its Parent Component. You can see Sidebar and Sidebar Links, also ATags, This Sidebar is parent and SidebarLinks are children, SidebarLinks also call a ATag which is another child element. You can see ‘name’ in Sidebar Component, and this name variable can access using in child child components.
this.props.variable_nameIn addition to this we have Refs, Lets talk about Refs
import React from "react"; import ReactDom,{Server} from "react-dom"; class TopSearch extends React.Component{ constructor(){ console.log("Initial") super() let myKeyword; this.state= { disabled: false, searchText: "Search" } } searchInputChange = (e) => { this.myKeyword = this.refs.keyword.value; }; searchButtonClick = (e) => { this.setState({disabled: true,searchText:"Searching..."}) this.startSearch(this.myKeyword) }; enterKeyPress = (e) => { if(e.which == 13){ this.startSearch(this.myKeyword) } }; startSearch =(value) => { setTimeout(()=>{ this.setState({disabled: false,searchText:"Search"}) this.unMountIt() },5000) }; unMountIt = () => { setTimeout(()=>{ ReactDom.unmountComponentAtNode(document.getElementById('top-search-bar')) },3000) }; render(){ return( <ul className="menu"> <li><input type="search" placeholder="Search" onChange={this.searchInputChange} ref="keyword" onKeyUp={this.enterKeyPress}/></li> <li><button disabled={(this.state.disabled)?true: false} type="button" className="button" onClick={this.searchButtonClick}> {this.state.searchText} </button></li> <CartIconOnTopBar/> </ul> ) } } class CartIconOnTopBar extends React.Component{ constructor(){ super() this.state = { cartItemCount: 0 } } openClassModal = () => { }; render(){ return( <li> <a href="#" onClick={this.openCartModal} className="cart-element"> <i className="fi-shopping-cart"></i> <span className="cart-count"> {this.state.cartItemCount} </span> </a> </li> ) } } export default TopSearch;Lets assume if we have a search input box, we want to access it’s value, what should we do? We can use refs to solve this problem. Above code has a search field
<ul> <li><input type="search" placeholder="Search" ref="keyword"/></li> <li><button disabled="disabled" type="button"> Search </button></li> </ul>You can see ref attributes, also you can see this.refs.keyword in searchInputChange function,
this.refs.keyword.valuecan used to get values form form elements, input, textarea etc. State are its own properties, all state properties are used inside component, we can pass state values to its child elements using props. State can be initially set on constructor function
this.state = {stateName: value, stateName2: value2}We can change state values using
this.setState({stateName: valueChanged})It can be called in all custom functions and most of the react component life cycle functions ( You can’t set states in componentWillUpdate method. For every changes react will re render component. Now we can moved to Life Cycle method, React have many life cycles
constructor(){ // First to load console.log("Initialization") } componentWillMount(){ // Second to load console.log("Component Will Mount") } componentDidMount(){ // Third to load console.log("Component Did Mount") } componentWillReceiveProps(){ // When props change console.log("Component Will Receive Props") } shouldComponentUpdate(){ // After props change, return true to re render and false to no change } componentWillUpdate(){ // When state or props change console.log("Component Will Updpate") } componentDidUpdate(){ // After state and props change, and re render happen console.log("Component Did Update") } componentWillUnmount(){ //Last state, it invoke after removal console.log("Component Will Unmount") }constructor – Initial life cycle method, which invoke when an component called, we can set states in this method componentWillMount : called before it render componentDidMount: called just after react element put all elements to real DOM, we can use this function to set some states, which cause re render componentWillRecieveProps: It can when props changed in parent components, it have an argumenet, nextProps shouldComponentUpdate: We can use return true to update element or false to prevent re-render, this has two argument oldProps, and newProps, we can check both and decide whether we want re-render or not componentWillUpdate, componentDidUpdate : Similar to WillMount and DidMount, but this won’t call during initial rendering, it call when state or props change. componentWillUnmount: It can when we remove element
ReactDom.unmountComponentAtNode(document.getElementById(‘top-search-bar‘))We can use above code to remove any react elements from Virtual DOM. I hope this will give a brief introduction to React JS, We will add more features as soon as possible, In our Next tutorial we will feature Flux architecture]]>