<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                這是一篇源自[官方博客](http://reactjs.cn/react/blog)?的[文章](http://reactjs.cn/react/blog/2013/11/05/thinking-in-react.html)。 在我看來, React 是較早使用 JavaScript 構建大型、快速的 Web 應用程序的技術方案。它已經被我們廣泛應用于 Facebook 和 Instagram 。 React 眾多優秀特征中的其中一部分就是,教會你去重新思考如何構建應用程序。 本文中,我將跟你一起使用 React 構建一個具備搜索功能的產品列表。 > **注意:** > > 如果你無法看到本頁內嵌的代碼片段,請確認你不是用?`https`?協議加載本頁的。 [TOC] ## 從原型( mock )開始 假設我們已經擁有了一個 JSON API 和設計師設計的原型。我們的設計師顯然不夠好,因為原型看起來如下: ![Mockup](https://box.kancloud.cn/2015-07-20_55acc1290e7e6.png) JSON接口返回數據如下: ~~~ [ {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} ]; ~~~ ## 第一步:拆分用戶界面為一個組件樹 你要做的第一件事是,為所有組件(及子組件)命名并畫上線框圖。假如你和設計師一起工作,也許他們已經完成了這項工作,所以趕緊去跟他們溝通!他們的 Photoshop 圖層名也許最終可以直接用于你的 React 組件名。 然而你如何知道哪些才能成為組件?想象一下,當你創建一些函數或對象時,用到一些類似的技術。其中一項技術就是[單一功能原則](http://en.wikipedia.org/wiki/Single_responsibility_principle),指的是,理想狀態下一個組件應該只做一件事,假如它功能逐漸變大就需要被拆分成更小的子組件。 由于你經常需要將一個JSON數據模型展示給用戶,因此你需要檢查這個模型結構是否正確以便你的 UI (在這里指組件結構)是否能夠正確的映射到這個模型上。這是因為用戶界面和數據模型在?_信息構造_?方面都要一致,這意味著將你可以省下很多將 UI 分割成組件的麻煩事。你需要做的僅僅只是將數據模型分隔成一小塊一小塊的組件,以便它們都能夠表示成組件。 ![Component diagram](https://box.kancloud.cn/2015-07-20_55acc12933b4e.png) 由此可見,我們的 app 中包含五個組件。下面我已經用斜體標示出每個組件對應的數據。 1. **`FilterableProductTable`?(橘色):**?包含整個例子的容器 2. **`SearchBar`?(藍色):**?接受所有?_用戶輸入( user input )_ 3. **`ProductTable`?(綠色):**?根據?_用戶輸入( user input )_?過濾和展示?_數據集合( data collection )_ 4. **`ProductCategoryRow`?(青色):**?為每個?_分類( category )_?展示一列表頭 5. **`ProductRow`?(紅色):**?為每個?_產品( product )_?展示一列 如果你仔細觀察?`ProductTable`?,你會發現表頭(包含“ Name ”和“ Price ”標簽)并不是單獨的組件。這只是一種個人偏好,也有一定的爭論。在這個例子當中,我把表頭當做`ProductTable`?的一部分,因為它是渲染“數據集合”的一份子,這也是?`ProductTable`?的職責。但是,當這個表頭變得復雜起來的時候(例如,添加排序功能),就應該單獨地寫一個`ProductTableHeader`?組件。 既然我們在原型當中定義了這個組件,讓我們把這些元素組成一棵樹形結構。這很簡單。被包含在其它組件中的組件在屬性機構中應該是子級: * `FilterableProductTable` * `SearchBar` * `ProductTable` * `ProductCategoryRow` * `ProductRow` ## 第二步: 利用 React ,創建應用的一個靜態版本 既然已經擁有了組件樹,是時候開始實現應用了。最簡單的方式就是創建一個應用,這個應用將數據模型渲染到 UI 上,但是沒有交互功能。拆分這兩個過程是最簡單的,因為構建一個靜態的版本僅需要大量的輸入,而不需要思考;但是添加交互功能卻需要大量的思考和少量的輸入。我們將會知道這是為什么。 為了創建一個渲染數據模型的應用的靜態版本,你將會構造一些組件,這些組件重用其它組件,并且通過?_props_?傳遞數據。?_props_?是一種從父級向子級傳遞數據的方式。如果你對?_state_概念熟悉,那么*_不要使用 state *_來構建這個靜態版本。 state 僅用于實現交互功能,也就是說,數據隨著時間變化。因為這是一個靜態的應用版本,所以你并不需要 state 。 你可以從上至下或者從下至上來構建應用。也就是說,你可以從屬性結構的頂部開始構建這些組件(例如,從?`FilterableProductTable`?開始),或者從底部開始(?`ProductRow`?)。在簡單的應用中,通常情況下從上至下的方式更加簡單;在大型的項目中,從下至上的方式更加簡單,這樣也可以在構建的同時寫測試代碼。 在這步結束的時候,將會有一個可重用的組件庫來渲染數據模型。這些組件將會僅有`render()`?方法,因為這是應用的一個靜態版本。位于樹形結構頂部的組件(`FilterableProductTable`?)將會使用數據模型作為 prop 。如果你改變底層數據模型,然后再次調用?`React.render()`?, UI 將會更新。查看 UI 如何被更新和什么地方改變都是很容易的,因為 React 的**單向數據流**(也被稱作“單向綁定”)保持了一切東西模塊化,很容易查錯,并且速度很快,沒有什么復雜的。 如果你在這步中需要幫助,請查看[?React 文檔](http://facebook.github.io/react/docs/)。 ### 穿插一小段內容: props 與 state 比較 在 React 中有兩種類型的數據“模型”: props 和 state 。理解兩者的區別是很重要的;如果你不太確定兩者有什么區別,請大致瀏覽一下[官方的 React 文檔](http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html)。 ## 第三步:識別出最小的(但是完整的)代表 UI 的 state 為了使 UI 可交互,需要能夠觸發底層數據模型的變化。 React 通過?**state**?使這變得簡單。 為了正確構建應用,首先需要考慮應用需要的最小的可變 state 數據模型集合。此處關鍵點在于精簡:_不要存儲重復的數據_。構造出絕對最小的滿足應用需要的最小 state 是有必要的,并且計算出其它強烈需要的東西。例如,如果構建一個 TODO 列表,僅保存一個 TODO 列表項的數組,而不要保存另外一個指代數組長度的 state 變量。當想要渲染 TODO 列表項總數的時候,簡單地取出 TODO 列表項數組的長度就可以了。 思考示例應用中的所有數據片段,有: * 最初的 products 列表 * 用戶輸入的搜索文本 * 復選框的值 * 過濾后的 products 列表 讓我們分析每一項,指出哪一個是 state 。簡單地對每一項數據提出三個問題: 1. 是否是從父級通過 props 傳入的?如果是,可能不是 state 。 2. 是否會隨著時間改變?如果不是,可能不是 state 。 3. 能根據組件中其它 state 數據或者 props 計算出來嗎?如果是,就不是 state 。 初始的 products 列表通過 props 傳入,所以不是 state 。搜索文本和復選框看起來像是 state ,因為它們隨著時間改變,也不能根據其它數據計算出來。最后,過濾的 products 列表不是 state ,因為可以通過搜索文本和復選框的值從初始的 products 列表計算出來。 所以最終, state 是: * 用戶輸入的搜索文本 * 復選框的值 ## 第四步:確認 state 的生命周期 OK,我們辨別出了應用的 state 數據模型的最小集合。接下來,需要指出哪個組件會改變或者說_擁有_這個 state 數據模型。 記住: React 中數據是沿著組件樹從上到下單向流動的。可能不會立刻明白哪個組件應該擁有哪些 state 數據模型。**這對新手通常是最難理解和最具挑戰的,**因此跟隨以下步驟來弄清楚這點: 對于應用中的每一個 state 數據: * 找出每一個基于那個 state 渲染界面的組件。 * 找出共同的祖先組件(某個單個的組件,在組件樹中位于需要這個 state 的所有組件的上面)。 * 要么是共同的祖先組件,要么是另外一個在組件樹中位于更高層級的組件應該擁有這個 state 。 * 如果找不出擁有這個 state 數據模型的合適的組件,創建一個新的組件來維護這個 state ,然后添加到組件樹中,層級位于所有共同擁有者組件的上面。 讓我們在應用中應用這個策略: * `ProductTable`?需要基于 state 過濾產品列表,`SearchBar`?需要顯示搜索文本和復選框狀態。 * 共同擁有者組件是?`FilterableProductTable`?。 * 理論上,過濾文本和復選框值位于?`FilterableProductTable`?中是合適的。 太酷了,我們決定了 state 數據模型位于?`FilterableProductTable`?之中。首先,給`FilterableProductTable`?添加?`getInitialState()`?方法,該方法返回?`{filterText: '', inStockOnly: false}`?來反映應用的初始化狀態。然后傳遞?`filterText`?和?`inStockOnly`給?`ProductTable`?和?`SearchBar`?作為 prop 。最后,使用這些 props 來過濾?`ProductTable`中的行,設置在?`SearchBar`?中表單字段的值。 你可以開始觀察應用將會如何運行:設置?`filterText`?為?`"ball"`?,然后刷新應用。將會看到數據表格被正確更新了。 ## 第五步:添加反向數據流 到目前為止,已經構建了渲染正確的基于 props 和 state 的沿著組件樹從上至下單向數據流動的應用。現在,是時候支持另外一種數據流動方式了:組件樹中層級很深的表單組件需要更新?`FilterableProductTable`?中的 state 。 React 讓這種數據流動非常明確,從而很容易理解應用是如何工作的,但是相對于傳統的雙向數據綁定,確實需要輸入更多的東西。 React 提供了一個叫做?`ReactLink`?的插件來使其和雙向數據綁定一樣方便,但是考慮到這篇文章的目的,我們將會保持所有東西都直截了當。 如果你嘗試在示例的當前版本中輸入或者選中復選框,將會發現 React 會忽略你的輸入。這是有意的,因為已經設置了?`input`?的?`value`?屬性,使其總是與從`FilterableProductTable`?傳遞過來的?`state`?一致。 讓我們思考下我們希望發生什么。我們想確保無論何時用戶改變了表單,都要更新 state 來反映用戶的輸入。由于組件只能更新自己的 state ,?`FilterableProductTable`?將會傳遞一個回調函數給?`SearchBar`?,此函數將會在 state 應該被改變的時候觸發。我們可以使用 input 的?`onChange`?事件來監聽用戶輸入,從而確定何時觸發回調函數。`FilterableProductTable`?傳遞的回調函數將會調用?`setState()`?,然后應用將會被更新。 雖然這聽起來有很多內容,但是實際上僅僅需要幾行代碼。并且關于數據在應用中如何流動真的非常清晰明確。 ## 就這么簡單 希望以上內容讓你明白了如何思考用 React 去構造組件和應用。雖然可能比你之前要輸入更多的代碼,記住,讀代碼的時間遠比寫代碼的時間多,并且閱讀這種模塊化的清晰的代碼是相當容易的。當你開始構建大型的組件庫的時候,你將會非常感激這種清晰性和模塊化,并且隨著代碼的復用,整個項目代碼量就開始變少了 :)。
                  <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>

                              哎呀哎呀视频在线观看