The Complementarity of

React.js and Web Components

React.js Conf 2015 | @AndrewRota

Blizzard of 2015
Image CC-SA 3.0 by Medeis

I ❤

Web Components

Web Components usher in a new era of web development based on encapsulated and interoperable custom elements that extend HTML itself. — Polymer Project

Custom Elements

Shadow DOM

HTML Imports

HTML Templates

Custom Elements


<my-element>Hello World.</my-element>

var MyElement = document.registerElement('my-element', {
    prototype: Object.create(HTMLElement.prototype)
});

Shadow DOM


// Create Shadow Root
var s = document.getElementById('my-element').createShadowRoot();

// Add Styles and Text
s.innerHTML += '<style>p { color: red; }</style>';
User agent shadow DOM
<my-custom-element customAttribute="foo"></my-custom-element>
<my-custom-element customAttribute="foo">
  <!-- SHADOW DOM -->
  <style>p { color: red; }</style>
  <div>
    <button name="button"><content></content></button>
    <p>Lorem Ipsum</p>
  </div>
  <script>doSomething();</script>
  <!-- /SHADOW DOM -->
</my-custom-element>

Web Components are portable, because their API is the web platform itself.

<input type="text" />

<a href="http://conf.reactjs.com/">Link!</a>

<video src="video.ogg" autoplay controls></video>

<x-calendar view="2015-01-29"></x-calendar>

<chart-pie values="[10, 20, 5, 50]"></chart-pie>

<my-custom-element customAttribute="foo"></my-custom-element>

I ❤

Virtual DOM

One-Way Data Flow

Ultra-High Performance

Synthetic Event System

Cohesive, Loosely Coupled Components

Client + Server Rendering

?

“I definitely think it's the wrong programming paradigm; I really hope that [web components] do not succeed.”

React or Web Components: Pick One?


Custom Elements
Shadow DOM

Encapsulation
Reusability
Portability





or


Virtual DOM
Synthetic Event System

One-Way Data Flow
Ultra-High Performance
Client + Server Rendering


Custom Elements
Shadow DOM

Encapsulation
Reusability
Portability





+


Virtual DOM
Synthetic Event System

One-Way Data Flow
Ultra-High Performance
Client + Server Rendering

<React/>

React

React

React


DOM

DOM

DOM

WC

WC

DOM

React.render(
  <my-custom-element>Web Components!!</my-custom-element>,
  document.getElementById('root')
);
ERROR in ./src/js/init.js
Module build failed:Error: Lower case component
names (my-custom-element) are no longer
supported in JSX: See
http://fb.me/react-jsx-lower-case

“The Whitelist Problem”

every time there's a new HTML/SVG tag, you can't use it until we add it to the whitelist. You can't add it to the whitelist until you update your existing codebase.”

v0.12-rc1

“To address this, we decided on a convention:
All JSX tags that start with a lower-case letter or contain a dash are treated as HTML.

…This also introduces the possibility to consume custom elements (Web Components)

The Web is continuously evolving.”

Goodbye, Whitelist

Removed unknown tag warning/whitelist. #2830

Goodbye, Warning

Removed unknown tag warning/whitelist. #2830

Hello, Custom Elements!

React.render(
  <my-custom-element>Web Components!!</my-custom-element>,
  document.getElementById('root')
);

Hello, Custom Elements!

React.render(
  React.createElement('my-custom-element', null, 'Web Components!!'),
  document.getElementById('root')
);

Best Practices for Building
Web Components for React.js

Best Practices for Building
Web Components for    React.js    Anything

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

Good Idea


<my-button></my-button>

Bad Idea


<my-application></my-application>

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

Component API


Attributes
<paper-toast text="Hello, world">

Methods
   getDOMNode().toggle()

Events
      <paper-toast onClick={this.handleClick}>

Custom Events

React.createClass({
  render: function() {
    return (
      <paper-toast ref="myCustomElement" text="Hello, World"></paper-toast>
    );
  },
  componentDidMount: function() {
     this.refs.myCustomElement.getDOMNode()
       .addEventListener('core-overlay-close-completed', doSomething);
  },
  componentWillUnmount: function() {
     this.refs.myCustomElement.getDOMNode()
       .removeEventListener('core-overlay-close-completed', doSomething);
  }
});
                    

Not All Web Components Are Created Equal

<google-map></google-map>

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

“Try to keep as many of your components as possible stateless.”

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

Your application is only as fast as your slowest component.

Web Components Should Be…


- Small

- Extremely Encapsulated

- As Stateless as Possible

- Performant

tl;dr Web Components should seem no different than native DOM elements.

corollary: Use Web Components in React.js as if they were native DOM elements.

<React/>

React

React

React


DOM

DOM

DOM

WC

WC

DOM


React

React within Web Components?



The Future (?)


Custom Attribute Support (Issue #2746)

Custom Event Support



Thanks!

@AndrewRota