<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                目前為止,我們已經學了如何用單個組件來展示數據和處理用戶輸入。下一步讓我們來體驗 React 最激動人心的特性之一:可組合性(composability)。 [TOC] ## 動機:關注分離 通過復用那些接口定義良好的組件來開發新的模塊化組件,我們得到了與使用函數和類相似的好處。具體來說就是能夠通過開發簡單的組件把程序的_不同關注面分離_。如果為程序開發一套自定義的組件庫,那么就能以最適合業務場景的方式來展示你的用戶界面。 ## 組合實例 一起來使用 Facebook Graph API 開發顯示個人圖片和用戶名的簡單 Avatar 組件吧。 ~~~ var Avatar = React.createClass({ render: function() { return ( <div> <ProfilePic username={this.props.username} /> <ProfileLink username={this.props.username} /> </div> ); } }); 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> ); } }); React.render( <Avatar username="pwh" />, document.getElementById('example') ); ~~~ ## 從屬關系 上面例子中,`Avatar`?擁有?`ProfilePic`?和?`ProfileLink`?的實例。`擁有者`?就是給其它組件設置?`props`?的那個組件。更正式地說, 如果組件?`Y`?在?`render()`?方法是創建了組件?`X`,那么?`Y`?就擁有?`X`。上面講過,組件不能修改自身的?`props`?- 它們總是與它們擁有者設置的保持一致。這是保持用戶界面一致性的關鍵性原則。 把從屬關系與父子關系加以區別至關重要。從屬關系是 React 特有的,而父子關系簡單來講就是DOM 里的標簽的關系。在上一個例子中,`Avatar`?擁有?`div`、`ProfilePic`?和`ProfileLink`?實例,`div`?是?`ProfilePic`?和?`ProfileLink`?實例的**父級**(但不是擁有者)。 ## 子級 實例化 React 組件時,你可以在開始標簽和結束標簽之間引用在React 組件或者Javascript 表達式: ~~~ <Parent><Child /></Parent> ~~~ `Parent`?能通過專門的?`this.props.children`?props 讀取子級。**`this.props.children`?是一個不透明的數據結構:**?通過?[React.Children 工具類](http://reactjs.cn/react/docs/top-level-api.html#react.children)?來操作。 ### 子級校正(Reconciliation) **校正就是每次 render 方法調用后 React 更新 DOM 的過程。**?一般情況下,子級會根據它們被渲染的順序來做校正。例如,下面代碼描述了兩次渲染的過程: ~~~ // 第一次渲染 <Card> <p>Paragraph 1</p> <p>Paragraph 2</p> </Card> // 第二次渲染 <Card> <p>Paragraph 2</p> </Card> ~~~ 直觀來看,只是刪除了`Paragraph 1`。事實上,React 先更新第一個子級的內容,然后刪除最后一個組件。React 是根據子級的_順序_來校正的。 ### 子組件狀態管理 對于大多數組件,這沒什么大礙。但是,對于使用?`this.state`?來在多次渲染過程中里維持數據的狀態化組件,這樣做潛在很多問題。 多數情況下,可以通過隱藏組件而不是刪除它們來繞過這些問題。 ~~~ // 第一次渲染 <Card> <p>Paragraph 1</p> <p>Paragraph 2</p> </Card> // 第二次渲染 <Card> <p style={{display: 'none'}}>Paragraph 1</p> <p>Paragraph 2</p> </Card> ~~~ ### 動態子級 如果子組件位置會改變(如在搜索結果中)或者有新組件添加到列表開頭(如在流中)情況會變得更加復雜。如果子級要在多個渲染階段保持自己的特征和狀態,在這種情況下,你可以通過給子級設置惟一標識的?`key`?來區分。 ~~~ render: function() { var results = this.props.results; return ( <ol> {results.map(function(result) { return <li key={result.id}>{result.text}</li>; })} </ol> ); } ~~~ 當 React 校正帶有 key 的子級時,它會確保它們被重新排序(而不是破壞)或者刪除(而不是重用)。?`務必`?把?`key`?添加到子級數組里組件本身上,而不是每個子級內部最外層 HTML 上: ~~~ // 錯誤! var ListItemWrapper = React.createClass({ render: function() { return <li key={this.props.data.id}>{this.props.data.text}</li>; } }); var MyComponent = React.createClass({ render: function() { return ( <ul> {this.props.results.map(function(result) { return <ListItemWrapper data={result}/>; })} </ul> ); } }); // 正確 :) var ListItemWrapper = React.createClass({ render: function() { return <li>{this.props.data.text}</li>; } }); var MyComponent = React.createClass({ render: function() { return ( <ul> {this.props.results.map(function(result) { return <ListItemWrapper key={result.id} data={result}/>; })} </ul> ); } }); ~~~ 也可以傳遞 object 來做有 key 的子級。object 的 key 會被當作每個組件的?`key`。但是一定要牢記 JavaScript 并不總是保證屬性的順序會被保留。實際情況下瀏覽器一般會保留屬性的順序,**除了**?使用 32位無符號數字做為 key 的屬性。數字型屬性會按大小排序并且排在其它屬性前面。一旦發生這種情況,React 渲染組件的順序就是混亂。可能在 key 前面加一個字符串前綴來避免: ~~~ render: function() { var items = {}; this.props.results.forEach(function(result) { // 如果 result.id 看起來是一個數字(比如短哈希),那么 // 對象字面量的順序就得不到保證。這種情況下,需要添加前綴 // 來確保 key 是字符串。 items['result-' + result.id] = <li>{result.text}</li>; }); return ( <ol> {items} </ol> ); } ~~~ ## 數據流 React 里,數據通過上面介紹過的?`props`?從擁有者流向歸屬者。這就是高效的單向數據綁定(one-way data binding):擁有者通過它的?`props`?或?`state`?計算出一些值,并把這些值綁定到它們擁有的組件的 props 上。因為這個過程會遞歸地調用,所以數據變化會自動在所有被使用的地方自動反映出來。 ## 性能提醒 你或許會擔心如果一個擁有者有大量子級時,對于數據變化做出響應非常耗費性能。值得慶幸的是執行 JavaScript 非常的快,而且?`render()`?方法一般比較簡單,所以在大部分應用里這樣做速度極快。此外,性能的瓶頸大多是因為 DOM 更新,而非 JS 執行,而且 React 會通過批量更新和變化檢測來優化性能。 但是,有時候需要做細粒度的性能控制。這種情況下,可以重寫?`shouldComponentUpdate()`方法返回 false 來讓 React 跳過對子樹的處理。參考?[React reference docs](http://reactjs.cn/react/docs/component-specs.html)?了解更多。 > 注意: > > 如果在數據變化時讓?`shouldComponentUpdate()`?返回 false,React 就不能保證用戶界面同步。當使用它的時候一定確保你清楚到底做了什么,并且只在遇到明顯性能問題的時候才使用它。不要低估 JavaScript 的速度,DOM 操作通常才是慢的原因。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看