ReactJS

Getting started

React itself is only

a View layer

Library

NOT a framework

React is a JavaScript library to build reusable UI components

Component-Based

Build encapsulated components that manage their own state

Compose them to make complex UIs

Component logic is written in JavaScript instead of templates

React provides a declarative library that keeps the DOM in sync with your data.

Declarative

Design simple views for each state in your application

React will efficiently update and render just the right components when your data changes

Declarative views make your code more predictable and easier to debug

Virtual DOM

Create lightweight description of component UI

Diff it with the old one

Compute minimal set of changes to apply to the DOM

Batch execute all updates

When state changes, the view is re-rendered

Clean

Clear, declarative programming model

 

Fast

Optimized DOM updates and less reflows

JSX

var Header = React.createClass({
        render: function () {
            return (
                <h1>Order header</h1>
            );
        }
});

Rendered to JavaScript, not HTML!

"use strict";

var Header = React.createClass({
    displayName: "Header",

    render: function render() {
        return React.createElement(
            "h1",
            null,
            "Order header"
        );
    }
});

JSX

  • Optional HTML-like markup
  • Declarative description of the UI inlined in JS code
  • Combines ease-of-use of templates with power of JavaScript

Component

var Header = React.createClass({
        render: function () {
            return (
                <h1>Employee Directory</h1>
            );
        }
});

Creating Components

  • Create the component using React.createClass()
  • Implement the render() function
  • Return the UI description

Component Rendering

  • Value returned by render() is not a DOM node
  • It’s a lightweight description of the UI
  • It's diffed with current description to perform the minimum set of changes to the DOM

Composition

    return React.createClass({
   
      /* 
        ...
      */

      render: function () {
   
        return (
          <div className="react-order-list">
            { this.props.orders.map(function (group) {
              return (
                <div key={ group.index }>
                  <LabelLine ordergroup={ group }/>
                  <OrderRows orders={ group.orders } toggleDetails={ toggleFn } 
                        openRow={openRow} searchTerm={ searchTerm }/>
                </div>
              )
            })}
          </div>
        );
      }
    });

Data flow

Properties passed by the parent are available in this.props in the child

Parent-to-child

Data flow

Text

Parent


 return (
    <LabelLine ordergroup={ group }/>
    <OrderRows orders={ group.orders }/>
 )

Data flow

Text

Child

var LabelLine = React.createClass({
      render: function () {
        return (
          this.props.ordergroup.orders.length ? 
            <h4 className="in-table-heading mb-capitalized">
            { this.props.ordergroup.label }
          </h4> : null
        );
      }
    });

Inverse Data flow

Pass event handler as a property

Child-to-Parent

Inverse Data flow

Parent

  var OrderRows = React.createClass({
      render: function () {
        var toggleFn = this.props.toggleDetails;
        return (
          <div>{ this.props.orders.map(function (order) {
            return <OrderRow order={order} key={ order.orderId }
             toggleDetails={ toggleFn } />
          })}</div>
        )
      }
    });

Inverse Data flow

Child

    var OrderRow = React.createClass({
      toggleDetails: function () {
        this.props.toggleDetails(this.props.order.orderId);
      },

      render: function () {
        return (
          <div className={ rowStyle } data-layout-wrap tabIndex="30"
            onClick={ this.toggleDetails } >
           /*...*/
      }
    });

shouldComponentUpdate

We are able to bypass rendering (and calling superExpensiveFunction) when it isn't needed

shouldComponentUpdate: function (nextProps) {
   return nextProps.openRow != this.props.openRow;
}

ngReact

Angular module that allows React Components to be used in AngularJS applications.

Greater performance than Angular can offer (two way data binding, Object.observe, too many scope watchers on the page) and React is typically more performant due to the Virtual DOM and other optimizations it can make

ngReact =

react-component

reactDirective

react-component

 Angular directive that delegates off to a React Component

<div class="div-table" data-ng-if="vm.items.length && !vm.loading"
   data-mb-react-order-list data-orders="vm.items" 
   data-selected-order-fn="vm.setSelectedOrder"
   data-selected-order="vm.selectedOrder" 
   data-send-order-email-fn="vm.sendEmail" 
   data-search-term="vm.appliedFilter.searchTerm"
   data-watch-depth="collection">
</div>

reactDirective

angular.module('mb2App.directives')
  .directive('mbReactOrderList', function (reactDirective) {
    'use strict';

    return reactDirective('ReactOrderListFactory', undefined, {
      restrict: 'A'
    });
  });
angular.module('mb2App.orderHistory.services')
  .factory('ReactOrderListFactory', function ($rootScope, $state, $filter) {
            ...
        return React.createClass({ 
        render: function () {
            ...
       }
    });
  });

Reactjs

By cherrypick

Reactjs

  • 2,630