React is a "javascript library for building user interfaces". It strictly focuses on the "V" in your MVC applications, and touts a blazing fast virtual DOM diff implementation.

JSXTransformer: in-browser transformer.

React Fundamentals

Virtual DOM

Whenever a ReactComponent is changing the state, we want to make as little changes to the DOM as possible.

How React deals with this: the ReactComponent is converted to the ReactElement. Now the ReactElement can be inserted to the virtual DOM, compared and updated fast and easily by the diff algorithm. This is done faster than it would be in the DOM. When React knows the diff - it’s converted to the low-level (HTML DOM) code, which is executed in the DOM. This code is optimised per browser.

Owner / Ownee

React refers to owner-ownee relationship when one component renders another component. Parent component is also called a composite.

An owner is the component that sets the props of other components. More formally, if a component X is created in component Y's render() method, it is said that X is owned by Y. A component cannot mutate its props — they are always consistent with what its owner sets them to. This fundamental invariant leads to UIs that are guaranteed to be consistent.

It's important to draw a distinction between the owner-ownee relationship and the parent-child relationship. The owner-ownee relationship is specific to React, while the parent-child relationship is simply the one from the DOM.

When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
<Parent><Child /></Parent>
Parent can read its children by accessing the special this.props.children prop. this.props.children is an opaque data structure.

An owner can only be a React Component, an ownee can be anything (component or basic html tag).

this.props.children

Access inner HTML element or element that's been nested inside a parent.

Usually, a component's children (this.props.children) is an array of components. However, when there is only a single child, this.props.children will be the single child component itself without the array wrapper. This saves an array allocation.

You can't access the children of your component through this.props.children. this.props.children designates the children being passed onto you by the owner. To access your own subcomponents, place refs on them.

React.Children

Provides utilities for dealing with this.props.children (which may alternatively be an array of components or a single child component).
array React.Children.map(object children, function fn [, object thisArg]): Invoke fn on every immediate child contained within children with this set to thisArg. If children is a keyed fragment or array it will be traversed: fn will never be passed the container objects. If children is null or undefined returns null or undefined rather than an array. React.Children.forEach(object children, function fn [, object thisArg]): Like React.Children.map() but does not return an array. number React.Children.count(object children): Return the total number of components in children, equal to the number of times that a callback passed to map or forEach would be invoked. object React.Children.only(object children): Return the only child in children. Throws otherwise. array React.Children.toArray(object children): Return the children opaque data structure as a flat array with keys assigned to each child. Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice this.props.children before passing it down.

Render method

React components implement a render() method that takes input data and returns what to display.  All React components have a render method.  Input data that is passed into the component can be accessed by render() via this.props.

Render is only allowed to return a single node.  Need to make sure that returning a parent node, and all elements are a child of that node.

Props

Can initialise with properties, which work just like HTML attributes.

Can also define the types of properties expecting, using propTypes objects.  Each key will be the property name.  Can also use getDefaultProps.

Prop Validation

React.createClass({  
  propTypes: {
    // You can declare that a prop is a specific JS primitive. By default, these
    // are all optional.
    optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,

    // Anything that can be rendered: numbers, strings, elements or an array
    // (or fragment) containing these types.
    optionalNode: React.PropTypes.node,

    // A React element.
    optionalElement: React.PropTypes.element,

    // You can also declare that a prop is an instance of a class. This uses
    // JS's instanceof operator.
    optionalMessage: React.PropTypes.instanceOf(Message),

    // You can ensure that your prop is limited to specific values by treating
    // it as an enum.
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // An object that could be one of many types
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // An array of a certain type
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // An object with property values of a certain type
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // An object taking on a particular shape
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // You can chain any of the above with `isRequired` to make sure a warning
    // is shown if the prop isn't provided.
    requiredFunc: React.PropTypes.func.isRequired,

    // A value of any data type
    requiredAny: React.PropTypes.any.isRequired,

    // You can also specify a custom validator. It should return an Error
    // object if the validation fails. Don't `console.warn` or throw, as this
    // won't work inside `oneOfType`.
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error(
          'Invalid prop `' + propName + '` supplied to' +
          ' `' + componentName + '`. Validation failed.'
        );
      }
    },

    // You can also supply a custom validator to `arrayOf` and `objectOf`.
    // It should return an Error object if the validation fails. The validator
    // will be called for each key in the array or object. The first two
    // arguments of the validator are the array or object itself, and the
    // current item's key.
    customArrayProp: React.PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
      if (!/matchme/.test(propValue[key])) {
        return new Error(
          'Invalid prop `' + propFullName + '` supplied to' +
          ' `' + componentName + '`. Validation failed.'
        );
      }
    })
  },
  /* ... */
});

State

A React component updates and maintains state. getInitialState is a function, returns an object.  Each key is a initial state.  Access with {this.state.key} (just like props).

To update state, call this.setState which takes an object which can overwrite or merge with the state.  SetState can be called in a custom function.

setState

Performs a shallow merge of nextState into current state. This is the primary method you use to trigger UI updates from event handlers and server request callbacks.

The first argument can be an object (containing zero or more keys to update) or a function (of state and props) that returns an object containing keys to update.

void setState(  
  function|object nextState,
  [function callback]
)

setState({mykey: 'my new value'}); It's also possible to pass a function with the signature function(state, props). This can be useful in some cases when you want to enqueue an atomic update that consults the previous value of state+props before setting any values. For instance, suppose we wanted to increment a value in state:

setState(function(previousState, currentProps) {  
  return {myInteger: previousState.myInteger + 1};
});

The second (optional) parameter is a callback function that will be executed once setState is completed and the component is re-rendered.

replaceState

Like setState() but deletes any pre-existing state keys that are not in nextState.

void replaceState(  
  object nextState,
  [function callback]
)

forceUpdate

void forceUpdate(  
  [function callback]
)

By default, when your component's state or props change, your component will re-render. However, if these change implicitly (eg: data deep within an object changes without changing the object itself) or if your render() method depends on some other data, you can tell React that it needs to re-run render() by calling forceUpdate().

Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child. React will still only update the DOM if the markup changes.

Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). This makes your component "pure" and your application much simpler and more efficient.

Stateless functional components

Most of the components you write will be stateless, simply composing other components. A simpler syntax for these components can take props as an argument and return the element you want to render:

// A functional component using an ES2015 arrow function:
var Aquarium = (props) => {  
  var fish = getFish(props.species);
  return <Tank>{fish}</Tank>;
};

// Or with destructuring and an implicit return, simply:
var Aquarium = ({species}) => (  
  <Tank>
    {getFish(species)}
  </Tank>
);

// Then use: <Aquarium species="rainbowfish" />

These components behave just like a React class with only a render method defined. Since no component instance is created for a functional component, any ref added to one will evaluate to null. Functional components do not have lifecycle methods, but you can set .propTypes and .defaultProps as properties on the function.

Refs

Can access specific references to individual components by defining a ref. These refs (references) are especially useful when you need to: find the DOM markup rendered by a component (for instance, to position it absolutely), use React components in a larger non-React application, or transition your existing codebase to React.

In order to get a reference to a React component, you can either use this to get the current React component, or you can use a ref to get a reference to a component you own.

When attaching a ref to a DOM component like <div />, you get the DOM node back; when attaching a ref to a composite component like <TextInput />, you'll get the React class instance.

The ref attribute can be a callback function, and this callback will be executed immediately after the component is mounted. The referenced component will be passed in as a parameter, and the callback function may use the component immediately, or save the reference for future use (or both).

var MyComponent = React.createClass({  
  handleClick: function() {
    // Explicitly focus the text input using the raw DOM API.
    if (this.myTextInput !== null) {
      this.myTextInput.focus();
    }
  },
  render: function() {
    // The ref attribute is a callback that saves a reference to the
    // component to this.myTextInput when the component is mounted.
    return (
      <div>
        <input type="text" ref={(ref) => this.myTextInput = ref} />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.handleClick}
        />
      </div>
    );
  }
});

ReactDOM.render(  
  <MyComponent />,
  document.getElementById('example')
);

Although string refs are not deprecated, they are considered legacy, and will likely be deprecated at some point in the future. Callback refs are preferred.

Refs return the cached instance of the component or element.

findDOMNode

A last option is ReactDOM.findDOMNode, which uses the DOM API directly to return the node (Node.nodeType). This is much less performant than the using refs to return the cached component from the virtual DOM.

displayName

JSX sets this value automatically;
string displayName

Component Lifecycle

Mounting

mounting: add component to the DOM.
unmounting: remove component from the DOM.
componentWillMount: immediately prior to mounting. Have access to state and props.
componentDidMount: immediately after mounting.  Have access to the component in the DOM.  Clean up any processes running. Initialization that requires DOM nodes should go here (i.e ref).

Updating

Only available for components passed directly into React.render:
componentWillReceiveProps: invoked when a mounted component receives new props. This method should be used to compare this.props and nextProps to perform state transitions using this.setState(). shouldComponentUpdate(object nextProps, object nextState): boolean: invoked when a component decides whether any changes warrant an update to the DOM. Implement this as an optimization to compare this.props with nextProps and this.state with nextState and return false if React should skip updating. componentWillUpdate(object nextProps, object nextState): invoked immediately before updating occurs. You cannot call this.setState() here. componentDidUpdate(object prevProps, object prevState): invoked immediately after updating occurs.

Unmounting

componentWillUnmount: called when will remove component from the DOM. Cleanup should go here.

Mounted

component.forceUpdate() can be invoked on any mounted component when you know that some deeper aspect of the component's state has changed without using this.setState().

Flux

Flux is a design pattern rather than a framework.  Two-way data binding is considered an anti-pattern, and flux promotes a uni-directional event (action) orientated model.

Flux applications have three major parts: the dispatcher, the stores, and the views (React components).

A unidirectional data flow is central to the Flux pattern, and the above diagram should be the primary mental model for the Flux programmer. The dispatcher, stores and views are independent nodes with distinct inputs and outputs.

The actions are simple objects containing the new data and an identifying type property.

The views may cause a new action to be propagated through the system in response to user interactions:

All data flows through the dispatcher as a central hub.

Actions are provided to the dispatcher in an action creator method, and most often originate from user interactions with the views.

The dispatcher then invokes the callbacks that the stores have registered with it, dispatching actions to all stores.

Within their registered callbacks, stores respond to whichever actions are relevant to the state they maintain. The stores then emit a change event to alert the controller-views that a change to the data layer has occurred.

Controller-views listen for these events and retrieve data from the stores in an event handler. The controller-views call their own setState() method, causing a re-rendering of themselves and all of their descendants in the component tree.

View is generally a React component, or otherwise a controller-view.  Controller-view is a reference to the root component which passes data down to children.

However, the application logic resides in the store: this is the area where all the work is done.  Store registers with dispatcher which actions (events) it is listening for.  When events occur, dispatcher sends a payload of that action to any stores that are registered to listen for that action. The store responds which may update the view.

The View can trigger an action, although doesn't know about action except by name or by type.

Dispatcher is queuing up all the actions and executing them in order that they arrive.

Redux

The first principle of Redux is that everything that changes in your application, including the data and the UI state, is contained in a single object, we call the state or the state tree.

The state tree is read only. Cannot modify or write to it. The only way to change the state is to dispatch an action. An action is a plain JavaScript object describing the change. The action is the minimal representation of the change to the data.

Pure and Impure Functions

The pure functions are the functions whose returned value depends solely on the values of their arguments. Pure functions have no observable side affects like network or database operations. They simply calculate the new value.

// Pure functions
function square(x) {  
  return x * x;
}
function squareAll (items) {  
  return items.map(square); // map returns a new array, so no side affects.
}
// Impure functions
function square(x) {  
  updateXInDatabase(x);
  return x * x;
}
function squareAll(items) {  
  for (let x = 0; i < items.length; i++ ) {
    items[i] = square(items[i]);
  }
}

The reducer function

The view layer is most predictable when it is described as a pure function of the application state. Redux complements this approach with another idea, that the state mutations in your app need to be described as a pure function that takes the previous state and the action being dispatched and returns the next state of your application.

The reducer has to be pure, and cannot modify the state given to it (has to return a new object).

Store methods

This store binds together the three principles of Redux. It holds the current application's state object. It lets you dispatch actions. When you create it, you need to specify the reducer that tells how state is updated with actions.

const { createStore } = Redux;  
const store = createStore(counter); // need to pass in the reducer that will manage state updates.  In this case, counter.

store.getState(); // retrieves the current state of the redux store  
store.dispatch({ type: 'INCREMENT'} );  // dispatches actions to change the state of the application

// subscribe lets you register a callback that the Redux store will call any time an action has been dispatched, so that you can update the UI of your application. It will reflect the current application state.

const render = () => {  
  document.body.innerText = store.getState();
}

store.subscribe(render);  
render();

document.addEventListener('click', () => {  
  store.dispatch({ type: 'INCREMENT' });
});

Patterns

Flux Stores / Actions vs Container Components

Flux Stores and Actions should always be used when the session is mutating.

Container components are components which are responsible for fetching data, and pass down data to child component/s via props.  The child component is responsible for rendering.  This allows the child component to be reused, and also allows the child component to fail loudly (using required PropTypes) if it does not receive its data.

Container components are concerned with how things work. They provide the data and behavior to presentational or other container components. They call Flux actions and provide these as callbacks to the presentational components. Are often stateful, as they tend to serve as data sources. Are usually generated using higher order components such as connect() from React Redux, createContainer() from Relay, or Container.create() from Flux Utils, rather than written by hand.

Presentational components are concerned with how things look. They don't have dependencies on the rest of the app, such as flux actions or stores. They don't specify how data is loaded or mutated. They rarely contain state, and only if UI state. They are written as functional components unless they need state or Lifecycle hooks.

Stateless functional components

In idiomatic React code, most of the components you write will be stateless, simply composing other components. The syntax for these components can take props as an argument and return the element you want to render:

// A functional component using an ES2015 (ES6) arrow function:
var Aquarium = (props) => {  
  var fish = getFish(props.species);
  return <Tank>{fish}</Tank>;
};

// Or with destructuring and an implicit return, simply:
var Aquarium = ({species}) => (  
  <Tank>
    {getFish(species)}
  </Tank>
);

// Then use: <Aquarium species="rainbowfish" />

Higher-order components

Higher-order components A higher-order component is just a function that takes an existing component and returns another component that wraps it.

Performance

Profiling available with the addon react-addons-perf.

From the console, start recording, perform actions, stop recording, then print results using:
React.addons.Perf.start();
React.addons.Perf.stop();
React.addons.Perf.printWasted(); Tells you how much time was wasted doing render tree construction and virtual DOM comparisons that did not result in a DOM modification.
React.addons.Perf.printInclusive() and React.addons.Perf.printExclusive(): print the times it took to render your components. React.addons.Perf.printDOM(); returns all DOM operations that took place when rendering the React trees. After your initial component is rendered, it is expected that future re-renders should be re-using / updating existing DOM nodes and not creating new ones.

Shallow compare

shallowCompare is a helper function to achieve the same functionality as PureRenderMixin while using ES6 classes with React.

If your React component's render function is "pure" (in other words, it renders the same result given the same props and state), you can use this helper function for a performance boost in some cases.

Ads Manager learnings

React.js Conf 2015 - Making your app fast with high-performance components Talk not addressing cssperf, GPU acceleration, or memory management.

Pure components

Pure components: render is deterministic: render only depends on props and state:

render() {  
  return (
    <div style={{width: this.props.width}}>
      {this.state.rows}
    </div>
  );
}

Why is pure renders key? Because re-renders are most expensive part of responsive app. Hooks that help:

shouldComponentUpdate() {  
  return false;
}

If component is pure, can check current props / state and only if changes do need to re-render.
PureRenderMixin:

var pureRenderMixin = React.addons.PureRenderMixin;  
React.createClass({  
  mixins: [PureRenderMixin]

  ...

})

If component is pure, this mixin insulates component from parent changes.

Data comparability

How PureRenderMixin works:

shouldComponentUpdate(nextProps, nextState) {  
  return (
    !shallowEqual(this.props, nextProps) ||
    !shallowEqual(this.state, nextState)
  );
}

Easy to tell if a key has changes on trivial examples, but state tree is complicated because expresses business/product.

Lesson from bricks and mortar retail when returning unopened items: if "box" came from same store, is unopened and have receipt, can give to clerk to check and will return money. Doesn't need to check the contents of the box ("deep equals").

Want a single store of truth with referential equality (red or blue). Need to turn to an immutable model: can quickly tell if something needs to change because have referential equality: ref1 === ref2 equivalent to checking receipt in store.

Separation of concerns

Separation of concerns important to obtain. Also gives performance wins.
In scrolling example, can't control re-renders because props changing so frequently. However, if InnerTable is pure, can do nothing regardless of what is occurring around it.

<OuterScroller scrollTop={props.offsetTop}>  
  <InnerTable width="123" style="blue" />
</OuterScroller>  

I.e. move to loosely coupled component model: get performance and separation of concerns.

Children create deep update trees.

The more nodes in the update tree, the slower the update. Also, deeply nested trees become harder to maintain because everything is opinionated with respect to where it is in the tree.

Also, children change over time every time. Children nullify PureRenderMixin. Children are expensive because make for apps that aren't performant.

Need to minimise use of children, and prevent swapping out if possible.

Instead, create independent children: not relying on parent to pass down everything it needs.

As policy, all higher level components that need to do data fetching are wrapped in a container. Container does data fetching and talks to stores, component renders markup. Ideally, container (data layer) doesn't have any children and ideally doesn't have any props. Not a strongly opinionated structure. Therefore can move them around because don't have opinionated nesting structure.

Should be able to reuse components, because doesn't care where gets its data from. Aggressive use of shouldComponentUpdate then allows for insulation.

Priorities:
1. Purity: deterministically rendered components that can utilise shouldComponentUpdate and PureRenderMixin to prevent needless re-renders.
2. Data comparability: use highly comparable data (immutability) and single source of truth.
3. Loose coupling: use for maintainability and performance.
4. Be careful with children: children are expensive and should be independent (don't be reliant on props, insulate children from parents as much as can). Childless containers that talk to stores directly. Last thing want is if one store updates for entire tree to re-render.

Immutable Data

Persistent Immutable Data Structures:
- persistent: a mutatitive API, yet when call API method will leave original unchanged and return new version - immutable: once created can never be changed

For example, push:

List.prototype.push = function(value) {  
  // 1. Make a copy
  var clone = deepCopy(this);
  // 2. edit the copy
  clone[clone.length] = value;
  // 3. return the copy
  return clone;
}

Works via a property called Structural Sharing: when make a copy, want to recycle as much of the old one as possible. This made possible because of structure called Directed Acyclic Graph (DAG).

Directed Graph refers to trees of nodes pointed in single direction. Acyclic means no part of graph can refer back to itself (can't have child point back to its parent).

If making 'changes', copy the elements of the graph that need to change back up to the root of the tree. Beyond that everything else can be pointed to new branch.

Can leave old structure in place (persistent) or can allow be garbage collected if lose reference to it.

Using Arrays and Objects

There's a version of the DAG called trie (from retrieve) that can use to model arrays and key-value pairs.

Arrays

Index Trie: Bitmap Vector Trie
A tree of nodes of arrays of fixed size. Bits in each array node. The index of an array is represented by the binary number, broken down into each octal. Generally use 32 bit nodes because maps nicely to hardware.

Objects

Hash Trie: Hash Array Mapped Trie
Nodes which arrays of fixed size. Some nodes are leaves (hold keys and values). Use function called hash in order to turn keys / strings into a number. Anything passed into hash, and 32-bit number is returned:
function hash(key: any): Number

Implementation as Trie, Interface as Lists and Maps (object literals).

J.C.R Licklider, Director of ARPA Information Processing. "Man-Computer Symbiosis" 1960.
Alan Kay, Xerox PARC, creator of SmallTalk. "The Early History of SmallTalk".
Phil Bagwell, Scala community leader. "Ideal Hash Trees" 2000.
Rich Hickey, creator of Clojure. "Simple Made Easy" 2011.

What problems does this solve?

JavaScript cannot take advantage of multi-threading (and direction to mobile and IoT is multi-core devices). Embracing immutability may enable JavaScript future.

Mutable objects complect Time and Value.

Rich Hickey, Idendity, value and Time:

var identity;  
identity = "value";  
identity = "next value";  
identity = "future value";  

Identity is a thing. Over time if move, a thing has a new value (coordinates). Can't go back and edit value.
Immutable data removes complexity: it's like mutable data except it has one fewer feature (can't edit it). Therefore, its simpler.

The Many Mutable Problem (Mutable state Stockholm Syndrome).
Object.observer (ES7) may be one approach but not that practable. Observe object, when it changes call callback.

Immutable data solves this state problem.

Memoisation (memoise function)

Relevant to shouldComponentUpdate().

Flux stores usually contain mutable data. Instead, should build with immutable data.

In Hickey model: Flux store is identity. New immutable values as time passes.