Petit-déjeuner Makina Corpus

Comment React va révolutionner le web

twitter.com/ ticabri

github.com/ enguerran

Enguerran Colson

Artisan développeur JavaScript et mobile

Que fait Makina Corpus ?

Les logiciels libres et l'open data

Les méthodes agiles

Le développement durable

Experts en logiciels libres , cartographie
et analyse de données , nous concevons
des applications métiers innovantes.

<!DOCTYPE html>
<html>
<head>
  <meta name="description" content="The simplest React Element">
  <script src="//fb.me/react-0.14.7.js"></script>
  <script src="//fb.me/react-dom-0.14.7.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div id="anchor"></div>

  <script>

  var mountNode = document.getElementById('anchor');

  var reactElement = React.createElement('p', {}, "Hello, World!");

  ReactDOM.render(reactElement, mountNode);

  </script>
</body>
</html>

Hello, World!

React, c'est quoi ?

<!DOCTYPE html>
<html>
<head>…</head>
<body>

  <div id="anchor">
    <p data-reactid=".0">Hello, World!</p>
  </div>

  <script>…</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
  <meta name="description" content="The simplest React Element">
  <script src="//fb.me/react-0.14.7.js"></script>
  <script src="//fb.me/react-dom-0.14.7.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div id="anchor"></div>

  <script>

  var mountNode = document.getElementById('anchor');

  var reactElement = React.createElement('p', {}, "Hello, World!");

  ReactDOM.render(reactElement, mountNode);

  </script>
</body>
</html>

Hello, World!

C'est une bibliothèque…

<!DOCTYPE html>
<html>
<head>…</head>
<body>

  <div id="anchor">
    <p data-reactid=".0">Hello, World!</p>
  </div>

  <script>…</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
  <meta name="description" content="The simplest React Element">
  <script src="//fb.me/react-0.14.7.js"></script>
  <script src="//fb.me/react-dom-0.14.7.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <div id="anchor"></div>

  <script>

  var mountNode = document.getElementById('anchor');

  var reactElement = React.createElement('p', {}, "Hello, World!");

  ReactDOM.render(reactElement, mountNode);

  </script>
</body>
</html>

Hello, World!

…de manipulation du DOM…

<!DOCTYPE html>
<html>
<head>…</head>
<body>

  <div id="anchor">
    <p data-reactid=".0">Hello, World!</p>
  </div>

  <script>…</script>
</body>
</html>

… en JavaScript …

var reactComponent = React.createClass({

  getInitialState: function() {
    return {
      seconds: 0
    };
  },

  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },

  componentWillUnmount: function() {
    clearInterval(this.interval);
  },

  tick: function() {
    this.setState({
      seconds: this.state.seconds + 1
    });
  },

  render: function() {
    return React.createElement('p', null, 'Secondes écoulées : ' + this.state.seconds);
  }

});

ReactDOM.render(React.createElement(reactComponent, null), mountNode);

… à base de composants

var reactComponent = React.createClass({

  getInitialState: function() {
    return {
      seconds: 0
    };
  },

  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },

  componentWillUnmount: function() {
    clearInterval(this.interval);
  },

  tick: function() {
    this.setState({
      seconds: this.state.seconds + 1
    });
  },

  render: function() {
    return React.createElement('p', null, 'Secondes écoulées : ' + this.state.seconds);
  }

});

ReactDOM.render(React.createElement(reactComponent, null), mountNode);

Web Composants

<video controls src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" />

Bootstrap

webcomponents.org

bosonic

polymer

x-tag

Foundation

Hierarchie de composants

  • FilterableProductTable (orange)

    • SearchBar (blue)

    • ProductTable (green)

      • ProductCategoryRow (turquoise)

      • ProductRow (red)

Hierarchie de composants

[
  {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
  {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
  {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
  {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
  {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
  {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];
<div>
  <SearchBar filterText={this.state.filterText}
             inStockOnly={this.state.inStockOnly}
             onUserInput={this.handleUserInput}/>
  <ProductTable products={this.props.products}
                filterText={this.state.filterText}
                inStockOnly={this.state.inStockOnly}>
    <ProductCategoryRow category={product.category}
                        key={product.category}/>
    <ProductRow product={product}
                key={product.name}/>
  </ProductTable>
</div>

Hierarchie de composants

Notifications de

messages non lus

<div class="notification">
  <span class="notification__fire"></span>
  <span class="notification__badge">99+</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__badge">4</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__bell"></span>
</div>
  • Ajouter des éléments
  • Supprimer des éléments
  • Réordonner des éléments
  • Modifier des éléments

DOM API

<div class="notification">
  <span class="notification__fire"></span>
  <span class="notification__badge">99+</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__badge">4</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__bell"></span>
</div>

Ajouter un badge

Mettre le badge à 4

Ajouter un badge

Ajouter du feu

Mettre le badge à 4

if (count > 99) {
  if (!hasFire()) {
    addFire();
  }
} else {
  if (hasFire()) {
    removeFire();
  }
}

if (count === 0) {
  if (hasBadge()) {
    removeBadge();
  }
} else {
  if (!hasBadge()) {
    addBadge();
  }
  var countText = count > 99 ? '99+' : count.toString();
}
<div class="notification">
  <span class="notification__fire"></span>
  <span class="notification__badge">99+</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__badge">4</span>
  <span class="notification__bell"></span>
</div>
<div class="notification">
  <span class="notification__bell"></span>
</div>

n(n-1)

n²-n

Une autre façon

		                                var notificationComposant;
if (count === 0) {
  notificationComposant =
    React.createElement("div", { "className": "notification" },
      React.createElement("span", { "className": "notification__bell" })
    );
} else if (count <= 99) {
  notificationComposant =
    React.createElement("div", { "className": "notification" },
      React.createElement("span", { "className": "notification__badge" }, count),
      React.createElement("span", { "className": "notification__bell" })
    );
} else {
  notificationComposant =
    React.createElement( "div", { "className": "notification" },
      React.createElement("span", { "className": "notification__fire" }),
      React.createElement("span", { "className": "notification__badge" }, "99+"),
      React.createElement("span", { "className": "notification__bell" })
    );
}
return notificationComposant;

On modélise les états et pas les transitions.

JSX

		                                var notificationComposant;
if (count === 0) {
  notificationComposant = (
    <div className="notification">
      <span className="notification__bell"></span>
    </div>
  );
} else if (count <= 99) {
  notificationComposant = (
    <div className="notification">
      <span className="notification__badge">{count}</span>
      <span className="notification__bell"></span>
    </div>
  );
} else {
  notificationComposant = (
    <div className="notification">
      <span className="notification__fire"></span>
      <span className="notification__badge">99+</span>
      <span className="notification__bell"></span>
    </div>
  );
}
return notificationComposant;

Questions

React propose une programmation déclarative ou impérative ?

Déclarative car elle permet d'exprimer ce qu'on veut (What). Une programmation impérative permet d'exprimer comment on veut quelque chose (How).

                              var numbers = [8,13,21,34,55];

// Imperative (How)
function imperative_sum(numbers) {
  var total = 0;
  for(var i = 0 ; i < numbers.length ; i++) {
    total += numbers[i];
  }
  return total;
}

// Declarative (What)
function declarative_sum(numbers) {
  return numbers.reduce(function(sum, current) {
    return sum + current;
  }, 0);
}
          

Questions

React permet d'écrire du code HTML dans du code JavaScript via JSX ?

Faux. Il n'y a pas d'HTML dans React. JSX est une écriture simplifiée de la fonction React.createElement en mode canada dry. C'est du sucre syntaxique.

                              function numberItem(number) {
  return (<li>{number}</li>);
}

function numbersList(numbers) {
  var list = numbers.map(numberItem);
  return (<ul>{list}</ul>);
}

function numberItemNoJSX(number) {
  return React.createElement("li",null, number);
}

function numbersListNoJSX(numbers) {
  var list = numbers.map(numberItemNoJSX);
  return React.createElement("ul", list);
}

Démo #1

Démo #1

<h3>Lecteur vidéo</h3>

<div class="videoplayerContainer"
     data-src="http://v2v.cc/~j/theora_testsuite/320x240.ogg">

  <div class="videoplayer" data-reactid=".0">
    <div data-reactid=".0.0">
      <video src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" data-reactid=".0.0.0">
      </video>
    </div>
    <div class="btn-group" data-reactid=".0.1">
      <button class="btn btn-default" data-reactid=".0.1.0">Lire</button>
      <button class="btn btn-default active" data-reactid=".0.1.1">Pause</button>
    </div>
  </div>
</div>

<div class="videoplayerContainer"
     data-src="http://techslides.com/demos/sample-videos/small.ogv">

  <div class="videoplayer" data-reactid=".1">
    <div data-reactid=".1.0">
      <video src="http://techslides.com/demos/sample-videos/small.ogv" data-reactid=".1.0.0">
      </video>
    </div>
    <div class="btn-group" data-reactid=".1.1">
      <button class="btn btn-default" data-reactid=".1.1.0">Lire</button>
      <button class="btn btn-default active" data-reactid=".1.1.1">Pause</button>
    </div>
  </div>
</div>

Démo #2

La communauté React

37 600+ stars

636 contributors

11 500+ questions

6play

Arte

Airbnb

BBC

Codecademy

Coursera

Dailymotion

Docker

Dropbox

Facebook

Feedly

Flipboard

IMDb

Imgur

Instagram

Khan Academy

Netflix

Paypal

Periscope

Reddit

Tesla Motors

Twitter - Fabric

WordPress.com

Yahoo

Des outils

Les ressources

  • React Blog, par Facebook team
  • Introduction à ReactJS, par putaindecode.fr
  • ReactJS, par Adam Solove
  • Decomplexifying Code with React, par Steven Luscher
  • Removing User Interface Complexity, or Why React is Awesome, par James Long
  • React.js Internals, par Nick Niemeir
  • React's diff algorithm, par Christopher Chedeau
  • React.js: Secrets of the Virtual DOM, par Pete Hunt
  • Learn Raw React ‒ no JSX, no Flux, no ES6, no Webpack… James K Nelson

Merci