React.js Workshop

淺入淺出 React.js

Denny Ku

我是誰

Denny Ku

  • Sudo:Front-end developer
  • 和沛科技:Front-end engineer
  • github: abalone0204

今天要講什麼

  • 為什麼 React 重要
  • 基本的 React 教學
  • 一般人懂的 React 教學

Outline

  • 概念
    • 簡介 MVC、MVVM
    • What is React.js
    • Pros & Cons
  • 環境建置
  • React basic
    • Data flow
    • State, Props, Life-cycle method
  • React intermediate
    • Router
    • Redux
    • Redux Saga
    • CSS Modules

基本上

就是我的工作流程

概念

前言

  • 每個人的定義的 MV* 可能都不一樣
  • 去爭吵什麼是 Model 、什麼是 Controller 沒有意義
  • 真正要在意的是這些想法在軟體架構上的意義

前言

  • 可變與不可預測的狀態是萬惡之源
  • 但需求永遠都是可變、不可預測的
  • 所以我們應該消滅製造需求的人
  • 所以我們應該要在讓可變的狀態變得好預測
    • ​Easy to reason about
    • 好讀
    • 符合常理

MVC 是什麼

MVVM 是什麼

多了一個 View Model

MVVM 是什麼

  • ViewModel 不需要瞭解 View 的實作細節
  • View 不需要知道 ViewModel 的實作細節,但是會聲明自己需要哪些數據、而且知道如何渲染畫面

 

所以

  • 我們需要一個 ViewModel 來做 action binding
  • 需要一個 state less 的 View

 

建置環境

建一個 React App 

React Create App

$> npm install -g react-create-app
$> create-react-app hello-world
$> cd hello-world && npm install && npm start

React basic

f(Data, Template) = View
  • 一個 Stateless 的 View 是什麼?
  • Function 的特性:
    • 好預測

Recap

  • ViewModel 不需要瞭解 View 的實作細節
  • View 不需要知道 ViewModel 的實作細節,但是會聲明自己需要哪些數據、而且知道如何渲染畫面

 

Thinking in React

  • 如果你是個前端工程師,你會怎麼拆解這個畫面?

 

關鍵的概念:hierarchy

恰巧 HTML 最大的優點就是

它是個 markup languate

它能夠很好的描述各種 hierarchy

Component base

  • 一次只要關注在一個小點上
  • 決定這個 View 需要什麼樣的資料

 

Web Component

  • HTML + JavaScript + CSS
<FilterableProductTable>
  <SearchBar />
  <ProductTable>
    <ProductCategoryRow/>
    <ProductRow/>
  </ProductTable>
</FilterableProductTable>
        

JSX

  • HTML + JavaScript + CSS
<FilterableProductTable>
  <SearchBar />
  <ProductTable>
    <ProductCategoryRow/>
    <ProductRow/>
  </ProductTable>
</FilterableProductTable>
        

Hello world

// /static/js/bundle.js
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
<!doctype html>
<html lang="en">
  <body>
    <div id="example"></div>
  </body>
  <script type="text/javascript" src="/static/js/bundle.js"></script>
</html>

Hello world

// /static/js/bundle.js
import ReactDOM from 'react-dom';
import Hello from 'components/Hello';

ReactDOM.render(
  <Hello />,
  document.getElementById('example')
);
<!doctype html>
<html lang="en">
  <body>
    <div id="example"></div>
  </body>
  <script type="text/javascript" src="/static/js/bundle.js"></script>
</html>
const Hello = () => (
  <h1>Hello, world!</h1>  
);

export default Hello;

What is View

f (Data, Template) -> View

const Hello = () => (
  <h1>Hello, world!</h1>  
);

export default Hello;
const Hello = ({text}) => (
  <h1>{text}</h1>  
);

export default Hello;

f () -> View

React 中的 Props 跟 State

// CSS 待會再說
<Hello text={"yo"}/>
const Hello = ({text}) => (
  <h1>{text}</h1>  
);

export default Hello;

這就是 Props

那 State 呢

<div className="App">
  <h1>Hello world</h1>
  <input type="text" ref='input'/>
  <button onClick={this.clickHandler}>
    send
  </button>
  <TodoList todos={todos} />
</div>
clickHandler = (e) => {
  const {
    value,
  } = this.refs.input
  const {
    todos,
  } = this.state; 
  this.setState({
      todos: todos.concat(value)
  }, ()=> {
    this.refs.input.value = '';
  })
}

Live demo

State 的壞處

  • 如果每一個小 component 都有自己的 state

State

State

State

State

gan gan gan

Make State great again

State

User action

還可以更好

這樣做的結果是會得到一個過度複雜的 Component

React intermediate

  • 這裡會介紹這些東西在做什麼以及該怎樣學

 

Redux

Redux

 

  • 優點:
    • 沒有 local state 了
    • functional way
    • 好讀、好寫、好測試
    • 會需要寫一些 boiler plate 的 code
  • 不足的地方:
    • 對於 Async 的 action 處理還不夠好

Redux - Async?

送出後不會馬上做完的事情

Redux -  學習資源

redux-saga

 

處理 Side effect、Async action 的 Middle ware

redux-saga - saga 是什麼

redux-saga - saga 是什麼

redux-saga - 學習資源

react-router

Single Page Application 的 Router 問題

關鍵概念:

If route is nested , then component should be nested.

官方 Repo

CSS Modules

CSS Modules


import cssModules from 'react-css-modules';
import styles from './styles.css';
/* eslint-disable global-require*/
const Loading = () => (
  <div styleName="container">
    <img
      styleName="loading-icon"
      src={require('../../../assets/components/loading-icon.png')} alt=""
    />
  </div>
);
/* eslint-enable */

export default cssModules(Loading, styles);
@keyframes spin { 100% {transform: rotate(360deg); }}

.container {
    position: relative;
    padding: 30px;
    text-align: center;
}

.loading-icon {
    animation: spin 0.7s linear infinite;
}

CSS Modules

  • 設置簡單
  • 沒有 global 污染問題
  • no more !important
  • 符合組件的開發思想

CSS Modules - 結論

  • 時間不夠了,總之讚讚讚

結論

  • React 可能會收掉
  • 但組件化的思想不會
  • 可以了解底下怎麼做到的
    • 但,越少需要寫 config 的東西最好
  • 你可以 follow vuejs, cyclejs 等等 library
    • 更好一點也可以 follow Reactive programming 的想法
    • 也可以 follow       或我的網誌

結論

  • 你使用的語言被人嘲笑
    職業被藐視
    解決問題的努力被視為噱頭
    自詡不弄髒手的人輕視你面對的問題
    執行引擎到處是實作者從未重視過的 Bug
    所有跨平台的承諾都在增加你要解決的問題
    UX認為要的效果很簡單
    QA給你的回報難對上問題
    最後,報酬通常低於平均水準

    你說,你想成為前端工程師

    •  

參考資料

淺入淺出我流 React.js

By Denny Ku

淺入淺出我流 React.js

  • 2,531