Facebook: React-Flux

近日前端火紅的議題
社群戰火持續燃燒中

Michael Hsu.tw Nov, 2014

NTUIM R02 BAEIR LAB 徐承志

沒錯,就只是導讀

因為也根本還沒在專案實作過

目前 v0.12 還不停更新

暫時不花太多心力在語法上

讓我們感受一下

React-Flux Design Pattern 

What's React

A JavaScript library for creating user interfaces.

Renders your UI and responds to events.

AKA: The V in MVC.

React Design

  1. Separation of concerns

  2. Re-render

  3. VDOM

Separation of concerns

大家都愛的關注點分離

Server-Side MVC

Rails, Express, Sails ...

Client-Side MVC

Angular.js ...

Model - View - Controller 三部分的邏輯要拆開,中間鬆散的綁在一起。

前端 MVC 思維流程大概是這樣

讓我們從另一個角度

Use components to separate your concerns.

Yahoo Mail Case

在 React 的世界中

Build components, not templates.

React Componets

用比較專業的說法:

A highly cohesive building block for UIs loosely coupled with other components.

高內聚 n. high cohesion

低耦合 n. low coupling

Components 優點

  • Reusable

  • Composable: 元件可層層組合

  • Unit testable

Re-render the whole app on every update

採取「一律重繪」的原則

在我大一時候的認知

所有網頁都是透過 Refresh (F5) 來更新頁面

Angular Data Binding

頁面上觸發 Event,有關 angular 的 data binding 進入消化循環 (watch list, dirty checking),進而操作 DOM ,re-Render 頁面。

大型專案非常多的話勒?

Web Worker?

Why React 效能好

VDOM!

Virtual DOM

讓 Re-Rendering 頁面變得廉價

VDOM

  • It’s a pure Javascript, in-memory representation of the DOM
  • 底層 API 的功勞:不直接與 DOM 接觸。
    1. 當頁面需要更動,先產生一個假的 Virtual DOM subtree 
    2. 跟原本的DOM 做 Diff (樹的比較很多博士在研究)
    3. 在記憶體內進⾏⾼效能運算與批次更新
  • 因為有效減少對 DOM 的操作以及批次更新,因⽽加快反應速度 => 60 FPS 不是夢想

React Design

  1. Separation of concerns

  2. Re-render

  3. VDOM

React Data-Flow

One-Way data flow

單向資料流  

Traditional Data Flows Type

  • No framework: Any component can communicate with any other component
  • Angular: 2-way data binding and $digest loop
  • Backbone: Pub-sub
  • React: 1-way data flow (類似 Pub-sub)

Angular 碰到的問題

點擊網頁觸發資料 Model 改變,進而影響其他的頁面的元素,頁面被動的更新難免會碰到漏掉的情況,尤其是在複雜的大型專案上。

React 思維

  • React 認為 UI 就是一個簡單的 State Machine。
  • 從 UI 的角度思考,UI 本身俱有多種 State,並且負責把這些狀態輸出呈現。
  • 這樣做可以輕易讓你的 UI 保持一致。
  • 只要單純更新 Component 的 State,接著根據狀態 Render 輸出新的 UI。
  • React 透過較有效率的方式協助你更新 DOM 。

React 思維

由狀態去驅動改變 Components

操作 State

this.state vs this.props

只有變動的資料才需要放到 state

setState(data, callback)

Example 1: Simple Component

<!DOCTYPE html>
<html>
<head>
  <title>Hello React</title>
  <script src="http://fb.me/react-0.12.0.js"></script>
  <script src="http://fb.me/JSXTransformer-0.12.0.js"></script>
</head>

<body>
  <div id="example"></div>
  <script type="text/jsx">
    // ... 待會的關注點
  </script>
</body>
</html>

Include React.js (0.12.0 版)

在瀏覽器將 JSX 編譯成 JS

進入點,剩下 dom 都在 react 裏生成

JSX: 在 JS 裡面寫 HTML

Example 1: Simple Component

var HelloWorld = React.createClass({
  render: function() {
    return (
      <p>
        Hello, <input type="text" placeholder="Your name here" />!
        It is {this.props.date.toTimeString()}
      </p>
    );
  }
});

setInterval(function() {
  React.render(
    <HelloWorld date={new Date()} />,
    document.getElementById('example')
  );
}, 500);

Create a component

props: Properties

Render a ReactElement into the DOM

Example 2: Multi Components

<!DOCTYPE html>
<html>
<head>
  <title>Hello React</title>
  <script src="http://fb.me/react-0.12.0.js"></script>
  <script src="http://fb.me/JSXTransformer-0.12.0.js"></script>
</head>

<body>
  <div id="example"></div>
  <script type="text/jsx">
    // ... 待會的關注點
  </script>
</body>
</html>

似曾相識?沒錯,只有進入點

Example 2: Multi Components

var Avatar = React.createClass({
  render: function() {
    return (
      <div>
        <ProfilePic username={this.props.username} />
        <ProfileLink username={this.props.username} />
      </div>
    );
  }
});

React.render(
  <Avatar username="pwh" />,
  document.getElementById('example')
);

Avatar owns the

div, ProfilePic and ProfileLink instances

var ProfilePic = React.createClass({
  render: function() {
    return (
      <img src={'http://graph.facebook.com/' + this.props.username + '/picture'} />
    );
  }
});
var ProfileLink = React.createClass({
  render: function() {
    return (
      <a href={'http://www.facebook.com/' + this.props.username}>
        {this.props.username}
      </a>
    );
  }
});

an owner is the component that sets the props of other components

Example 3: State

<!DOCTYPE html>
<html>
<head>
  <title>Hello React</title>
  <script src="http://fb.me/react-0.12.0.js"></script>
  <script src="http://fb.me/JSXTransformer-0.12.0.js"></script>
</head>

<body>
  <div id="example"></div>
  <script type="text/jsx">
    // ... 待會的關注點
  </script>
</body>
</html>

似曾相識?沒錯,只有進入點

Example 3: State

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'unlike';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>

    );
  }
});

React.renderComponent(
  <LikeButton />,
  document.getElementById('example')
);

setState(data, callback) ,這個方法會把資料 data 整合進 this.state 接著重新渲染元件。

Component Lifecycle

Component Lifecycle

What's Flux

Application architecture for building client-side web applications

Flux

  • Unidirectional data flow architecture

  • just an architecture, not a framework.

  • not MVC,可以看成 MC 的功能

No two-way binding

因為 two-way binding 會造成串聯式的觸發更新(cascading updates),會讓結果難以預期。

Flux 的概念很簡單

1. Views 驅動 update(data) 事件

2. Action 將 data 送到 Dispatcher

 

 

 

3. Dispatcher 播送 payload 給所有 Stores

4. NodeJS’s EventEmitter 播送給 Views

5. View 跟 Store 拿 State

1

2

3

4

payload

5

主要元素

  • Dispatcher: 調度中心

  • Stores: state & logic 

  • Views: React components

  • Actions: helper methods

太過抽象

直接開始 Trace Code

前情提要

  1. Browserify: Bundling Node Modules for the Browser
  2. Gulp: The Streaming Build System
  3. LiveScript: a language which compiles to JavaScript.

Quick Starter Project 

Flux 的概念很簡單

1. Views 驅動 update(data) 事件

2. Action 將 data 送到 Dispatcher

 

 

 

3. Dispatcher 播送 payload 給所有 Stores

4. NodeJS’s EventEmitter 播送給 Views

5. View 跟 Store 拿 State

1

2

3

4

payload

5

等等,結束了?

That's all,
剩下語法大家各自努力

據說學習曲線

結論

TonyQ: 選擇 framework 之前應該要認識一下 framework。至少要瞭解各 framework 特色、特長,不要變成矇眼選項,這些東西並不是隨便選一個就好的。

Reference

Made with Slides.com