React. js頂尖開發:建立使用者介面的JavaScript 函式庫(第二版)1-2


React 本質

  1. React本質是個狀態機(state machine)
  2. React只關注兩件事:(1)更新DOM; (2)回應事件。
  3. React是MVC中的V(View),意即React只處理「視圖」。

React 優點

  1. JS 元素的狀態變更、重新渲染頁面會非常緩慢,意即 native DOM的讀取和更新是非常消耗性能的
  2. React 有自己的 Virtual DOM,並且利用Diff算法計算Virtual DOM 和 native DOM的差異,其優點在於:(1)只更新必要的部分; (2)最小化回流(reflow)。


Component

書中範例是用Class componenet寫法

  1. 自訂元件
  2. 動態值:大括號
  3. 子節點

自訂元件

var Divider = React.createClass({
    render: function(){
        return (
            <div className="divider">
                <h2>Quetions</h2><hr/>
            </div>
        );
    }
})

動態值

JSX會渲染 {...} 裡的動態值,書中介紹以下常用寫法:

寫法1. 變數

簡單的值或數字可用變數

var text='Questions';
<h2>{text}</h2>   // <h2>Questions</h2>
寫法2. 函式

複雜邏輯可用函式

function dateToString(d){
    return [
        d.getFullYear(),
        d.getMonth()+1,
        d.getDate()
    ].join('-');
};

<h2>{dateToString(new Date())}</h2>   // <h2>2014-10-18</h2>
寫法3. 陣列

React會自動把陣列每項元素渲染成一個節點

var text=['hello', 'world'];
<h2>{text}</h2>   // <h2>helloworld</h2>

子節點

React用一個特殊的元件屬性陣列 - this.prop.children 來捕捉標籤中包含的所有子節點

// JSX
var Divider = React.createClass({
    render: function(){
        return (
            <div className="divider">
                <h2>{this.props.children}</h2><hr/>
            </div>
        );
    }
});

// HTML
<Divider>Questions</Divider>



JSX

JavaScript XML 是一種用於React元件的標記語法,每個JSX標記映射到一個JS函式,雖然與HTML相似,卻有與HTML不同的以下特性:

  1. HTML屬性命名
  2. CSS命名
  3. 屬性:可用動態變數或函式設定; 選擇語句
  4. Non-DOM 特殊屬性
  5. 事件
  6. 註解

HTML屬性命名

  1. class → className
  2. for → htmlFor: <label htmlFor="for-text" ... />

CSS命名

都是camelCase方式命名,不可用原來的-

var styles = {
    borderColor: "#999",
    borderThickness: "1px"
};
React.renderComponent(<div style={styles}>...</div>, node);

JSX屬性

<div> id="some-id" class="'some-class-name'">...</div>

寫法1. 變數
var surveyQuestionId = this.props.id;
var classes = 'some-class-name';

// ...

<div id={surveyQuestionId} className={classes}></div>
寫法2. 取得函式結果

<div id={this.getSurveyId()}>...</div>

選擇語句

<div className={if(isComplete) { 'is-complete' } } }>...</div>是不好的表達方式,可以改用以下替代方案:

  1. 三元邏輯
  2. 變數
  3. 函式
  4. && operator
三元邏輯
render: function(){
    return <div className={this.state.isComplete ? 'is-complete' : '';}>...</div>;
}
變數

三元邏輯有時會難以閱讀,這時可以替三元邏輯的語法新增為一個變數。

getIsComplete: function(){
    return this.state.isComplete ? 'is-complete' : '';
},
render: function(){
 var isComplete = this.getIsComplete();   // 先給變數
 return <div className={isComplete}>...</div>
}
函式

因為上述範例是用函式取得三元邏輯的結果,也能省略使用變數,直接呼叫函式。

getIsComplete: function(){
    return this.state.isComplete ? 'is-complete' : '';
},
render: fucntion(){
    return <div className={this.getIsComplete()}></div>;   // 直接使用函式
}
&& operator

上述範例遇到值為null或是false的狀況不會輸出任何東西,這時可用&&運算子省略原範例的''寫法

render: function(){
    return <div className={this.state.isComplete && 'is-complete'}></div>
}

範例表示 this.state.isCompletetrue 才會使用字串 is-complete

Non-DOM 特殊屬性

  1. key
  2. ref
  3. dangerouslySetInnerHTML
key

用來唯一識別元件

ref

即參考(reference)。 ref 允許父元件保存一個指向子元件的參考,以便在渲染函式外使用,ref的定義方式如下:

render: function () {
    return <div>
        <input ref="myInput" ... />
    </div>;
}

之後可在任一元件用 this.refs.myInput 存取這個參考。透過這個參考存取的物件稱為「支援實作(backing instance)」。要注意的是,它不是實際的DOM,若要存取實際的DOM節點可用 this.refs.myInput.getDOMNode()

dangeouslySetInnerHTML

此JSX特殊屬性是用來設置原生的HTML,可於要用字串操作DOM的第三方函式庫的時候,利用此屬性設定HTML內容為字串。要注意的是,此屬性不推薦且應避免使用。使用方式如下先設置包含 __html 的物件,再指定給此屬性。

render: function () {
    var htmlString = {
        __html: "<span>this is an html string</span>"
    };
    return <div dangeouslySetInnerHTML={htmlString}></div>;
}

※這個設置HTML字串的方式似乎有其他解法

事件

  1. onClick
  2. onChange
  3. Class component事件的正確範例:
    handleClick: function (e) {...};
    render: function () {
     return <div onClick={this.handleClick}>...</div>;
    }
    
  4. Class component事件的錯誤範例:由於React會自動綁定(bind)一個元件的所有方法,所以不必特地手動綁定函式的執行環境。
    handleClick: function (e) {...};
    render: function () {
     return <div onClick={this.handleClick.bind(this)}>   // incorrect
    }
    

註解

// 1. 子節點
<div>
    {/*
        comment
    */}
    <input name="email" placeholder="Email Address" />
</div>


// 2. 內嵌於屬性
<div>
    <input
        /*
            多行註解
        */
        name="email"
        placeholder="Email Address" />
</div>

<div>
    <input
        name="email"  // 單行註解
        placeholder="Email Address" />
</div>
#React






你可能感興趣的文章

克努斯-莫里斯-普拉特演算法(KMP Algorithm)

克努斯-莫里斯-普拉特演算法(KMP Algorithm)

Math.(floor/ceil/round) in JavaScript

Math.(floor/ceil/round) in JavaScript

[學學ReactNative] DAY1 - 前言與動機:為何選擇 React Native?

[學學ReactNative] DAY1 - 前言與動機:為何選擇 React Native?






留言討論