Ch03 React/JSX/Component 簡介

Facebook 自己有提供 Test Utilities,但因爲不夠好用,因此目前主流開發社羣比較傾向使用 Airbnb 團隊開發的 enzyme,其能夠與市面上常見的測試工具(Mocha、Karma、Jest 等)搭配使用。其中 Jest 是 Facebook 所開發的單元測試工具,其主要基於 Jasmine 所創建的測試框架。Jest 除了支援 JSDOM 外,也能夠自動模擬 (mock) 透過 require() 進來的模組,讓開發者能夠更專一在目前被測試的模組中。

Component PropType 防呆機制

在 React 設計時除了提供 props 預設值設定(Default Prop Values)外,也提供了 Prop 的驗證(Validation)機制,讓整個 Component 設計更加穩健:html

//  注意組件開頭第一個字母都要大寫class MyComponent extends React.Component {
        // render 是 Class based 組件惟一必須的方法(method)
        render() {
                return (
                        <div>Hello, World!</div>
                );
        }
}

// PropTypes 驗證,若傳入的 props type 不符合將會顯示錯誤MyComponent.propTypes = {
  todo: React.PropTypes.object,
  name: React.PropTypes.string,
}

// Prop 預設值,若對應 props 沒傳入值將會使用 default 值MyComponent.defaultProps = {
 todo: {}, 
 name: '', 
}
 
 
 
 
 

Component 就像個狀態機(State Machine),並且也有生命週期(Life Cycle)

Component 就像個狀態機(State Machine),根據不一樣的 state(透過  setState() 修改)和 props(由父元素傳入),Component 會出現對應的顯示結果。而人有生老病死,組件也有生命週期。透過操做生命週期處理函數,能夠在對應的時間點進行 Component 須要的處理,關於更詳細的組件生命週期介紹咱們會再下一個章節進行更一步說明。
 

一概重繪(Always Redraw)和單向資料流(Unidirectional Data Flow)

在 React 世界中,props 和 state 是影響 React Component 長相的重要要素。其中 props 都是由父元素所傳進來,不能更改,若要更改 props 則必須由父元素進行更改。而 state 則是根據使用者互動而產生的不一樣狀態,主要是透過 setState() 方法進行修改。當 React 發現 props 或是 state 更新時,就會重繪整個 UI。固然你也可使用 forceUpdate() 去強迫重繪 Component。而 React 透過整合 Flux 或 Flux-like(例如:Redux)能夠更具體實現單向資料流(Unidirectional Data Flow),讓資料流的管理更爲清晰。
 
 
 
 
 
 

在 JavaScript 裏寫 CSS:Inline Style

在 React Component 中 CSS 使用 Inline Style 寫法,全都封裝在 JavaScript 當中:前端

const divStyle = {
  color: 'red',
  backgroundImage: 'url(' + imgUrl + ')',
};

ReactDOM.render(<div style={divStyle}>Hello World!</div>, document.getElementById('app'));
React 思路認爲使用 Component 比起模版(Template)和顯示邏輯(Display Logic)更能實現關注點分離的概念,而搭配 JSX 能夠實現聲明式  Declarative(注重 what to),而非命令式  Imperative(注重 how to)的程式撰寫方式:
 

Facebook 上面按贊功能

以 Facebook 上面按贊功能來講,如果命令式 Imperative 寫法大約會是長這樣:react

if(userLikes()) {
  if(!hasBlueLike()) {
    removeGrayLike();
    addBlueLike();
  }
} else {
  if(hasBlueLike()) {
    removeBlueLike();
    addGrayLike();
  }
}

如果聲明式 Declarative 則是會長這樣:git

if(this.state.liked) {
  return (<BlueLike />);
} else {
  return (<GrayLike />);
}
 
 
js中map函數
 
 

map 方法能夠方便的迭代數組,map 方法會迭代數組中的每個元素,並根據回調函數來處理每個元素,最後返回一個新數組。注意,這個方法不會改變原始數組。github

在咱們的例子中,回調函數只有一個參數,即數組中元素的值 (val 參數) ,但其實,你的回調函數也能夠支持多個參數,譬如:元素的索引index、原始數組arr。數組

使用 map 方法來爲 oldArray 中的每一項增長3,而且在 newArray 中保存它們。 oldArray 不該該被改變。瀏覽器

代碼:安全

var oldArray = [1,2,3,4,5];

var newArray = oldArray.map(function(val){return val+3;});
 
 

3. 轉換成 JavaScript

JSX 最終會轉換成瀏覽器能夠讀取的 JavaScript,如下爲其規則:app

React.createElement(
  string/ReactClass, // 表示 HTML 元素或是 React Component
  [object props], // 屬性值,用物件表示
  [children] // 接下來參數皆爲元素子元素
)

解析前(特別注意在 JSX 中使用 JavaScript 表達式時使用 {} 括起,以下方範例的 text,裏面對應的是變數。若需但願放置通常文字,請加上 ''):框架

var text = 'Hello React';
<h1>{text}</h1><h1>{'text'}</h1>

解析完後:

var text = 'Hello React';
React.createElement("h1", null, "Hello React!");
另外要特別要注意的是因爲 JSX 最終會轉成 JavaScript 且每個 JSX 節點都對應到一個 JavaScript 函數,因此在 Component 的  render 方法中只能回傳一個根節點(Root Nodes)。例如:如有多個  <div> 要  render 請在外面包一個 Component 或  <div><span> 元素

5. 屬性

在 HTML 中,咱們能夠透過標籤上的屬性來改變標籤外觀樣式,在 JSX 中也能夠,但要注意  class 和  for 因爲爲 JavaScript 保留關鍵字用法,所以在 JSX 中使用  className 和  htmlFor 替代。
class HelloMessage extends React.Component {
  render() {
    return (
      <div className="message">
        <p>Hello React!</p>
      </div>
    );
  }
}

Boolean 屬性

在 JSX 中預設只有屬性名稱但沒設值爲 true,例如如下第一個 input 標籤 disabled 雖然沒設值,但結果和下面的 input 爲相同:

<input type="button" disabled />;
<input type="button" disabled={true} />;

反之,如果沒有屬性,則預設預設爲 false

<input type="button" />;
<input type="button" disabled={false} />;
 
 

6. 擴展屬性

在 ES6 中使用 ... 是迭代物件的意思,能夠把全部物件對應的值迭代出來設定屬性,但要注意後面設定的屬性會蓋掉前面相同屬性:

var props = {
  style: "width:20px",
  className: "main",
  value: "yo", 
}

<HelloMessage  {...props} value="yo" />

// 等於如下React.createElement("h1", React._spread({}, props, {value: "yo"}), "Hello React!");
 

7. 自定義屬性

如果但願使用自定義屬性,可使用 data-

<HelloMessage data-attr="xd" />
 

8. 顯示 HTML

一般爲了不資訊安全問題,咱們會過濾掉 HTML,若須要顯示的話可使用:
<div>{{_html: '<h1>Hello World!!</h1>'}}</div>
 

9. 樣式使用

在 JSX 中使用外觀樣式方法以下,第一個 {} 是 JSX 語法,第二個爲 JavaScript 物件。與通常屬性值用 - 分隔不一樣,爲駝峯式命名寫法:

<HelloMessage style={{ color: '#FFFFFF', fontSize: '30px'}} />
 

10. 事件處理

事件處理爲前端開發的重頭戲,在 JSX 中透過 inline 事件的綁定來監聽並處理事件(注意也是駝峯式寫法),更多事件處理方法請參考官網

<HelloMessage onClick={this.onBtn} />
相關文章
相關標籤/搜索