Steps to build a modern web application with React

jonathan.xi@ge.com

Items

  • Why React
  • Steps
    • Quick Start
    • React + Redux + React Router
    • Front-end and Back-end separation
    • Performance Tuning
  • Thoughts

Why React

  • Easy
  • Component-based Architecture
  • Virtual Dom
  • Learn Once, Write Anywhere
  • Great Devtools
  • Great community

Easy

  • JSX
  • React Component

Sample: Hello Message

All test-able JavaScript

Component-based Architecture

Component-based Architecture - Sample

Component-based Architecture - Sample

Component-based Architecture - Sample

Component-based Architecture - Benefits

  • SRP
  • Loose Coupling
  • Parallel Development
  • Resuable Components
  • Increase Maintainability/Scalability/Extensibility

Virtual Dom

Old way's Performance Tuning - Dom Scripting

  • Dom batch update from documentFragment to document
  • Dom batch update at clonednode, then switch original node with cloned one
  • Dom batch update at hidden node, then display the node

Virtual Dom

Virtual Dom - Benefits

  • Good performance.
  • Hand over the dirty work to the library, keep focus at business logic.

Learn Once Run Everywhere

LORE - Isomorphic/Universal JavaScript - SEO

LORE - Isomorphic/Universal Apps

Great DevTools

React DevTools

Redux DevTools

  • Persist state on page reloading
  • Time travelling
  • Skip (Cancel) actions
  • Reorder actions

React Hot Loader

Great Community & Ecosystem

Great Community & Ecosystem

Great Community & Ecosystem

Great Community & Ecosystem

Why React

  • Easy to learn and get started
  • Component-based Architecture add -ilities
  • Virtual Dom - fast
  • Learn Once, Write Anywhere
  • Great Devtools
  • Great community

Steps to build Web Application with React

  • Quick Start
    • Setup JavaScript Development Environment
    • Create React App
  • React + Redux + React Router
  • Front-end and Back-end separation
  • Performance Tuning
  • Demo
  • Overal Diagram

Quick Start

  • Setup JavaScript Development Environment
  • Create React App

Setup JavaScript Development Environment

Expectations for IDE

  • Code auto formatting/fixing & linting
  • Code Navigation
  • Auto complete
  • VCS integration
  • Debugging

VS Code

  • IntelliSense
    • code-completion
    • parameter-info
    • quick-info
    • member-lists
    • code-navigation
  • Debug code right from the editor
  • Git commands built-in
  • VCS integration
  • Debugging
  • Plugins for auto-formatting/linting etc.

Install VS Code

Create React App

BoilerPlate X -> Create React App
  • Built-in Webpack/dev server Configuration
    • JS, CSS, Images Loader
    • Proxy
  • Test - Jest
  • Supported Language Features and Polyfills
    • ES6
    • Exponentiation Operator
    • Object Rest/Spread Properties
    • Dynamic import()
    • Class Fields and Static Properties
    • Object.assign/fetch/Promise
    • Async/Await
  • PWA

Supported Language Features and Polyfills

ES6

  • arrows
  • classes
  • enhanced object literals
  • template strings
  • destructuring
  • default + rest + spread
  • let + const
  • iterators + for..of
  • modules
  • promises

Exponentiation Operator(ES2016 Stage 3)


// x ** y

let squared = 2 ** 2;
// same as: 2 * 2

let cubed = 2 ** 3;
// same as: 2 * 2 * 2
                    

// x **= y

let a = 2;
a **= 2;
// same as: a = a * a;



let b = 3;
b **= 3;
// same as: b = b * b * b;
                    

Object Rest/Spread Properties(Stage 3)


let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
                    

let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
                    

Dynamic import(Stage 3)


// modueA.js
const moduleA = 'Hello';

export { moduleA };
                    

// App.js
import React, { Component } from 'react';

class App extends Component {
  handleClick = () => {
    import('./moduleA')
      .then(({ moduleA }) => {
        // Use moduleA
      })
      .catch(err => {
        // Handle failure
      });
  };

  render() {
    return (
      
); } } export default App;

Class Fields and Static Properties(stage 2)


//before
class DataGrid extends React.Component {
  constructor() {
    super();
    this.state = {
      items: [],
    };


  ...
  }
DataGrid.propTypes = {
  options: PropTypes.objectOf(PropTypes.any),
  columns: PropTypes.arrayOf(PropTypes.object),
  rows: PropTypes.arrayOf(PropTypes.object),
  events: PropTypes.arrayOf(PropTypes.func),
};

DataGrid.defaultProps = {
  options: {
    rowHeight: 25,
    forceFitColumns: true,
  },
  columns: [],
  rows: [],
  events: [],
};
                    

Class Fields and Static Properties(stage 2)


// after
class DataGrid extends React.Component {
  static propTypes = {
   options: PropTypes.objectOf(PropTypes.any),
   columns: PropTypes.arrayOf(PropTypes.object),
   rows: PropTypes.arrayOf(PropTypes.object),
   events: PropTypes.arrayOf(PropTypes.func),
  };

  static defaultProps = {
    options: {
      rowHeight: 25,
      forceFitColumns: true,
    },
    columns: [],
    rows: [],
    events: [],
  };
  state = {
    items: [],
  };
}
                    

Async & Await(ES2017 stage 3)


// before
function asyncTask () {  
  return functionA()
    .then((valueA) => functionB(valueA))
    .then((valueB) => functionC(valueB))
    .then((valueC) => functionD(valueC))
    .catch((err) => logger.error(err))
}
// after
async function asyncTask () {  
  try {
    const valueA = await functionA()
    const valueB = await functionB(valueA)
    const valueC = await functionC(valueB)
    return await functionD(valueC)
  } catch (err) {
    logger.error(err)
  }
}
                    

They are all yours!


npm -g create-react-app
create-react-app my-app
                    

React Stack

React + Redux + React Router

React

  • JSX
  • Functional and Class Components
  • Rules

What is JSX

  • JSX is a preprocessor step that adds XML syntax to JavaScript.
  • Just like XML, JSX tags have a tag name, attributes, and children.

JSX makes programming easier

  • You can embed any JavaScript expression in JSX.
  • JSX is an Expression.
  • You may use quotes to specify string literals as attributes,
  • You may also use curly braces to embed a JavaScript expression.

Functional and Class Components

  • Functional component
  • 
    function Welcome(props) {
      return 

    Hello, {props.name}

    ; }
  • Class component
  • 
    class Welcome extends React.Component {
      render() {
        return 

    Hello, {this.props.name}

    ; } }

Functional Components

  • Has props
  • No State
  • No this/class
  • No React component lifecyle methods

Class Components

  • Has props
  • Can have state
  • Has this
  • Have Lifecycle methods

Class Components Lifecycle methods

  • Mounting
    • constructor()
    • componentWillMount()
    • render()
    • componentDidMount()
  • Updating
    • componentWillReceiveProps()
    • shouldComponentUpdate()
    • componentWillUpdate()
    • render()
    • componentDidUpdate()
  • Unmounting
    • componentWillUnmount()

Rules

Redux

  • Organizing application state with Redux
  • Dumb and Smart Components
  • Flux Standard Action
  • Reducer Structure

Organizing application state with Redux

Dumb(Presentational) and smart(Container) components

Presentational Components Container Components
Purpose How things look (markup, styles) How things work (data fetching, state updates)
Aware of Redux No Yes
To read data Read data from props Subscribe to Redux state
To change data Invoke callbacks from props Dispatch Redux actions
Are written By hand Usually generated by React Redux

Flux standard action

  • An action MUST
    • be a plain JavaScript object.
    • have a type property.
  • An action MAY
    • have an error property.
    • have a payload property.
    • have a meta property.
  • An action MUST NOT include properties other than type, payload, error, and meta.

Reducer Structure

  • Domain data: data that the application needs to show, use, or modify
  • App state: data that is specific to the application's behavior
  • UI state: data that represents how the UI is currently displayed
  • 
    {
        domainData1 : {},
        domainData2 : {},
        appState1 : {},
        appState2 : {},
        ui : {
            uiState1 : {},
            uiState2 : {},
        }
    }
                            

Use Ducks Pattern to reduce code boilerplate

React Router

  • Bind UI & URL using React Router
  • Philosophy
  • <Router>
  • <Route>
  • <Switch>

Bind UI & URL using React Router

Philosophy

  • Dynamic Routing
  • Nested Routes
  • Responsive Routes

<Router>

  • <BrowserRouter>
  • <HashRouter>
  • <MemoryRouter>
  • 
    import { BrowserRouter as Router } from 'react-router-dom';
    <Router>
      <Route path="/" component={App} />
    </Router>
                            

<Route> render methods

  • <Route component>
  • 
    <Route path="/user/:username" component={User}/>
    const User = ({ match }) => {
      return 

    Hello {match.params.username}!

    }
  • <Route render>
  • 
    <Route path="/home" render={() => 
    Home
    }/>
  • <Route children>

Route props

  • All three render methods will be passed the same three route props: match, location, history
  • history
    • history.push
    • history.replace
  • match
    • match.parms
    • match.url
  • location
  • 
    {
      key: 'ac3df4', // not with HashHistory!
      pathname: '/somewhere'
      search: '?some=search-string',
      hash: '#howdy',
      state: {
        [userDefined]: true
      }
    }
                            

<Switch>

  • Renders the first child <Route> or <Redirect> that matches the location.
  • 
    // before:
    
    <Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/>
    // after: <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/>

Front-end and Back-end separation

Why separation

  • Start work quick
  • Divide work and work parallel
  • Deployment felixiblity

Problem: Cross origin requests

Test requests with Proxy

Performance Tuning

Insepct performance issues with Chrome Dev Tool

Use Page Speed to analyze your website performance

Demo: react-sample

Overall Diagram

Thoughts

React is great! But...

from jQuery to React is not easy

Idea: React Core + jQuery Page Development

Idea: React Core + jQuery Page Development - Sample

Good Performance + Low cost

Summary

  • Why React
  • Steps
    • Quick Start
    • React + Redux + React Router
    • Front-end and Back-end separation
    • Performance Tuning
  • Thoughts
Happy Coding!

Resources