亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

React思維方式·譯

helloworldcoding / 2395人閱讀

摘要:搜索文本和多選框因為會發(fā)生變化,且不能通過計算得出,所以是狀態(tài)。最后,過濾過的產(chǎn)品列表,可以通過原始產(chǎn)品列表搜索文本和多選框值計算出來,因此它不是狀態(tài)。從傳入的回調(diào)函數(shù)會調(diào)用,從而更新組件。

在使用JavaScript開發(fā)大型、快速的網(wǎng)頁應(yīng)用時,React是我們的首選。在Facebook和Instagram,React很好地減少了我們的工作量。
React最強(qiáng)大部分之一,是讓你在開發(fā)應(yīng)用的同時,按照開發(fā)應(yīng)用的思路去思考。這篇文章,將指導(dǎo)你通過幾個步驟,用React開發(fā)一個可搜索數(shù)據(jù)表

從一個模型開始

假設(shè)我們已經(jīng)有了一個JSON API和一個設(shè)計師設(shè)計的模型??雌饋硐襁@樣:

我們JSON API返回的數(shù)據(jù)看起來像這樣:

[
  {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"}
];
第一步:將UI分解為組件結(jié)構(gòu)

首先,在模型圖上框處每個組件(和子組件),并給組件命名。如果與設(shè)計師一起工作,他可能已經(jīng)心中有數(shù),不妨和他聊聊。他們Photoshop圖層名可能就能成為你的組件名!

但如何劃分父組件子組件呢?就像創(chuàng)建一個函數(shù)或?qū)ο笠粯?。其中之一是單一職?zé)原則,理想情況下,一個組件僅做一件事。如果一個組件太大,它應(yīng)該被分解為更小的子組件。

如果經(jīng)常把JSON數(shù)據(jù)模型展現(xiàn)給用戶,你會發(fā)現(xiàn),若模型創(chuàng)建正確,UI(以及組件結(jié)構(gòu))能很好的反映數(shù)據(jù)。這是因為UI和數(shù)據(jù)模型一定程度都是依附于信息架構(gòu)的,這意味著,將UI分解為組件并不是最重要的,最重要的是,被分解的組件能準(zhǔn)確表現(xiàn)你數(shù)據(jù)模型的一部分。

可以看出,我們的app有五個組件,我們用斜體表示每個組件所代表的數(shù)據(jù)。

FilterableProducTable(可過濾產(chǎn)品表,橙色):包含整個示例

SearchBar(搜索欄,藍(lán)色):接收用戶輸入

ProductTable(產(chǎn)品表,綠色):根據(jù)用戶輸入,展示和過濾數(shù)據(jù)集

ProductCategoryRow(產(chǎn)品分類行,藍(lán)綠色):顯示為每個分類的頭部

ProductRow(產(chǎn)品行,紅色):每個產(chǎn)品顯示為一行

觀察ProductTable,你會發(fā)現(xiàn)表頭(包含“Name”和“Price”標(biāo)簽部分)未被劃分為一個組件。表頭是否做為組件屬于個人偏好,至于使用哪種方式,以下可以作為參考。本例中,表頭作為ProductTable的一部分,因為表頭屬于渲染的數(shù)據(jù)集的一部分,所以表頭在ProductTable的職責(zé)范圍內(nèi)。但如果表頭變得更為復(fù)雜(如為添加排序功能),將表頭分離為ProductTableHeader更合理。

現(xiàn)在,我們已經(jīng)將模型劃分為了組件,接著要安排組件的層次結(jié)構(gòu)。這并不難,模型中一個組件出現(xiàn)在另一個組件的內(nèi)部,在層次結(jié)構(gòu)呈現(xiàn)為它的一個子級。

FilterableProductTable

SearchBar

ProductTable

ProductCategeoryRow

ProductRow

第二步:創(chuàng)建React靜態(tài)版本
class ProductCategoryRow extends React.Component {
  render() {
    return {this.props.category};
  }
}

class ProductRow extends React.Component {
  render() {
    var name = this.props.product.stocked ?
      this.props.product.name :
      
        {this.props.product.name}
      ;
    return (
      
        {name}
        {this.props.product.price}
      
    );
  }
}

class ProductTable extends React.Component {
  render() {
    var rows = [];
    var lastCategory = null;
    this.props.products.forEach(function(product) {
      if (product.category !== lastCategory) {
        rows.push();
      }
      rows.push();
      lastCategory = product.category;
    });
    return (
      {rows}
Name Price
); } } class SearchBar extends React.Component { render() { return (

{" "} Only show products in stock

); } } class FilterableProductTable extends React.Component { render() { return (
); } } var PRODUCTS = [ {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"} ]; ReactDOM.render( , document.getElementById("container") );

現(xiàn)在,你已經(jīng)有了組件的層次結(jié)構(gòu),是時候?qū)崿F(xiàn)這個app了。最簡單的方式,利用數(shù)據(jù)模型渲染一個無交互的UI版本。創(chuàng)建組件靜態(tài)版本需要敲很多鍵盤,無需過多思考,而添加交互效果需要很多思考,不需要敲很多鍵盤,這正是極好的解耦過程。

用數(shù)據(jù)模型創(chuàng)建app的靜態(tài)版本,你在創(chuàng)建組件時會想著復(fù)用其它組件,想著用屬性來傳遞數(shù)據(jù),而屬性是父級向子級傳遞數(shù)據(jù)的方式。即便你熟悉狀態(tài)的概念,創(chuàng)建靜態(tài)版本時也不要用任何狀態(tài)。狀態(tài)僅用作交互,狀態(tài)數(shù)據(jù)隨時間而變化,因為靜態(tài)版本無需任何交互,所以沒必要使用任何狀態(tài)。

在層級結(jié)構(gòu)中,既可以自上而下開始創(chuàng)建組件(從FilterableProductTable開始),也可以自下而上開始創(chuàng)建組件(從ProductRow開始)。簡單的例子中,自上而下的方式往往更簡單,對于大型項目來說,自下而上的方式更簡單,更容易測試。

該步完成時,你已經(jīng)有了一些可復(fù)用的組件,這些組件渲染了你的數(shù)據(jù)模型。靜態(tài)版本的組件僅有render()方法。頂層組件(FilterableProductTable)會把數(shù)據(jù)模型作為一個屬性。如果數(shù)據(jù)模型發(fā)生變化,再次調(diào)用ReactDOM.render(),UI會被更新。你可以很容易的看出UI是如何被更新的,哪兒發(fā)生了改變。React的單向數(shù)據(jù)流(也叫單向數(shù)據(jù)綁定),使得一切變得模塊化,變得快速。

簡述:屬性與狀態(tài)

屬性和狀態(tài)是React中的兩種數(shù)據(jù)模型,理解兩者的區(qū)別非常重要。如果你無法確定兩者的區(qū)別,請瀏覽官方文檔

第三步:確定描述UI的最少狀態(tài)

為了讓UI可以交互,需要能夠觸發(fā)數(shù)據(jù)模型發(fā)生改變。React的狀態(tài)能讓此變得簡單。

為了能正確的創(chuàng)建app,你要考慮app需要的最少狀態(tài)。關(guān)鍵在于不重復(fù),使用最少的狀態(tài),計算出所有你需要的數(shù)據(jù)。例如,你創(chuàng)建一個TODO列表,只需要保留一個TODO項數(shù)組,不需要再使用一個變量來保存TODO項數(shù)量,當(dāng)你需要渲染TODO項數(shù)目時,使用TODO項數(shù)組長度即可。

考慮示例應(yīng)用中所有的數(shù)據(jù),我們有:

原始產(chǎn)品列表

用戶輸入的搜索文本

多選框的值

過濾過的產(chǎn)品列表

簡單地問三個問題,讓我們過一遍,看看哪些是狀態(tài):

是否為從父組件傳入的屬性?如果是,或許不是狀態(tài)

是否是隨時間不變的?如果是,或許不是狀態(tài)

是否能通過組件中的其他狀態(tài)或?qū)傩杂嬎愠鰜??如果是,不是狀態(tài)

原始產(chǎn)品列表是從屬性傳入的,因此不是狀態(tài)。搜索文本和多選框因為會發(fā)生變化,且不能通過計算得出,所以是狀態(tài)。最后,過濾過的產(chǎn)品列表,可以通過原始產(chǎn)品列表、搜索文本和多選框值計算出來,因此它不是狀態(tài)。

最終,我們的狀態(tài)有:

用戶輸入的搜索文本

多選框的值

第四步:確定狀態(tài)應(yīng)該放置的位置
class ProductCategoryRow extends React.Component {
  render() {
    return ({this.props.category});
  }
}

class ProductRow extends React.Component {
  render() {
    var name = this.props.product.stocked ?
      this.props.product.name :
      
        {this.props.product.name}
      ;
    return (
      
        {name}
        {this.props.product.price}
      
    );
  }
}

class ProductTable extends React.Component {
  render() {
    var rows = [];
    var lastCategory = null;
    this.props.products.forEach((product) => {
      if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) {
        return;
      }
      if (product.category !== lastCategory) {
        rows.push();
      }
      rows.push();
      lastCategory = product.category;
    });
    return (
      {rows}
Name Price
); } } class SearchBar extends React.Component { render() { return (

{" "} Only show products in stock

); } } class FilterableProductTable extends React.Component { constructor(props) { super(props); this.state = { filterText: "", inStockOnly: false }; } render() { return (
); } } var PRODUCTS = [ {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"} ]; ReactDOM.render( , document.getElementById("container") );

OK,我們已經(jīng)確定了app的最少狀態(tài)。接下來,我們要確定哪個組件是可變的,或者說狀態(tài)屬于哪個組件。

記住,React在層級及結(jié)構(gòu)中,數(shù)據(jù)向下流動。這或許不能馬上清楚狀態(tài)究竟屬于哪個組件。這經(jīng)常也是初學(xué)者認(rèn)識React最有挑戰(zhàn)性的部分。所以,按照以下步驟,弄清這個問題:

對于應(yīng)用中的每個狀態(tài):

確認(rèn)每個需要這個狀態(tài)進(jìn)行渲染的組件

找到它們共有的父組件(層級結(jié)構(gòu)中,所有需要這個狀態(tài)的組件之上的組件)

讓共有父組件,或者比共有父組件更高層級的組件持有該狀態(tài)

如果你找不到合適的組件持有該狀態(tài),創(chuàng)建一個新的組件,簡單持有該狀態(tài)。把這個組件插入層級結(jié)構(gòu)共有父組件之上

將這個策略用到我們的應(yīng)用中:

ProductTable要根據(jù)狀態(tài)過濾產(chǎn)品列表,SearchBar要顯示搜索文本和多選框狀態(tài)

共有父組件是FilterableProductTable

FilterableProductTable持有過濾文本和多選框值很合理

Cool,就這樣決定把狀態(tài)放置到FilterableProductTable。首先,在FilterableProductTableconstructor中添加示例屬性this.state = {filterText: "", inStockOnly: false} ,來初始化狀態(tài)。然后,將filterTextisStockOnly作為屬性傳入ProductTableSearchBar。最后,使用這些屬性過濾ProductTable中的行,和設(shè)置SearchBar中表單的值

第五步:添加反向數(shù)據(jù)流
class ProductCategoryRow extends React.Component {
  render() {
    return ({this.props.category});
  }
}

class ProductRow extends React.Component {
  render() {
    var name = this.props.product.stocked ?
      this.props.product.name :
      
        {this.props.product.name}
      ;
    return (
      
        {name}
        {this.props.product.price}
      
    );
  }
}

class ProductTable extends React.Component {
  render() {
    var rows = [];
    var lastCategory = null;
    this.props.products.forEach((product) => {
      if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) {
        return;
      }
      if (product.category !== lastCategory) {
        rows.push();
      }
      rows.push();
      lastCategory = product.category;
    });
    return (
      {rows}
Name Price
); } } class SearchBar extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.props.onUserInput( this.filterTextInput.value, this.inStockOnlyInput.checked ); } render() { return (
this.filterTextInput = input} onChange={this.handleChange} />

this.inStockOnlyInput = input} onChange={this.handleChange} /> {" "} Only show products in stock

); } } class FilterableProductTable extends React.Component { constructor(props) { super(props); this.state = { filterText: "", inStockOnly: false }; this.handleUserInput = this.handleUserInput.bind(this); } handleUserInput(filterText, inStockOnly) { this.setState({ filterText: filterText, inStockOnly: inStockOnly }); } render() { return (
); } } var PRODUCTS = [ {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"} ]; ReactDOM.render( , document.getElementById("container") );

目前為止,我們已經(jīng)用屬性和狀態(tài),創(chuàng)建了具有在層級結(jié)構(gòu)中至上而下的數(shù)據(jù)流。現(xiàn)在,是時候支持反向的數(shù)據(jù)流動,讓底層表單組件能夠更新FilterableProductTable中的狀態(tài)。

React的單向數(shù)據(jù)流動使得程序更加清晰易懂,但相比雙向數(shù)據(jù)綁定,確實需要多打些代碼。

如果你嘗試在當(dāng)前示例中,輸入文本或選擇多選框,會發(fā)現(xiàn)React忽略了你的輸入。這是故意的,因為我們要設(shè)置inputvalue屬性要恒等于FilterableProductTable傳入的狀態(tài)。

思考下我們期望的狀況。我們希望,表單中無論何時發(fā)生改變,用戶的輸入要能夠更新狀態(tài)。因為組件應(yīng)該只更新自己的狀態(tài),所以FilterableProductTable會將回調(diào)函數(shù)傳遞給SearchBar,SearchBar會在要更新狀態(tài)時調(diào)用回調(diào)函數(shù)。我們用onChange事件通知狀態(tài)更新。從FilterableProductTable傳入的回調(diào)函數(shù)會調(diào)用setState(),從而更新組件。

雖然聽起來有點復(fù)雜,但是也就添加幾行代碼。它非常清晰地表現(xiàn)出了app中的數(shù)據(jù)流動。

就這樣

希望此文能帶給你使用React創(chuàng)建組件和應(yīng)用的思路。盡管你可能需要打比平時更多的代碼,但記住,代碼看著總是遠(yuǎn)比打著的時候多,并且這些代碼都是模塊化、清晰而易讀的。當(dāng)你開始開發(fā)大型組件庫的時候,你將會慶幸React的數(shù)據(jù)流清晰和模塊化的特性,并且隨著代碼的復(fù)用,代碼規(guī)模會開始縮小。

原文鏈接

thinking-in-react

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/81609.html

相關(guān)文章

  • ()React hooks:它不是一種魔法,只是一個數(shù)組——使用圖表揭秘提案規(guī)則

    摘要:它并不是實際在內(nèi)部的工作方式,而且它只是一個提案,在未來都會有可能發(fā)生變化。這意味著,數(shù)據(jù)的存儲是獨立于組件之外的。因此,有一個訣竅就是你需要思考作為一組需要一個匹配一致的指針去管理的數(shù)組染陌譯。 原文地址:https://medium.com/@ryardley/... 譯文:染陌 (Github) 譯文地址:https://github.com/answershuto/Blog 轉(zhuǎn)...

    fjcgreat 評論0 收藏0
  • 】渲染Elements

    摘要:注不做翻譯是中最小的構(gòu)建部件。在里渲染讓我們看一下在下面有在你文件中無處不在的標(biāo)簽我們會把這元素成為元素因為的所有東西都會放在這個元素里面。通過方法,我們能吧渲染到我們根節(jié)點上。更新被渲染的是不可變的。 下面是react官方文檔的個人翻譯,如有翻譯錯誤,請多多指出原文地址:https://facebook.github.io/re...特別感謝Hevaen,同時也向豪大React群所有...

    LoftySoul 評論0 收藏0
  • [] 前端攻略-從路人甲到英雄無敵二:JavaScript 與不斷演化的框架

    摘要:一般來說,聲明式編程關(guān)注于發(fā)生了啥,而命令式則同時關(guān)注與咋發(fā)生的。聲明式編程可以較好地解決這個問題,剛才提到的比較麻煩的元素選擇這個動作可以交托給框架或者庫區(qū)處理,這樣就能讓開發(fā)者專注于發(fā)生了啥,這里推薦一波與。 本文翻譯自FreeCodeCamp的from-zero-to-front-end-hero-part。 繼續(xù)譯者的廢話,這篇文章是前端攻略-從路人甲到英雄無敵的下半部分,在...

    roadtogeek 評論0 收藏0
  • 1月份前端資源分享

    摘要:更多資源請文章轉(zhuǎn)自月份前端資源分享視頻前端技術(shù)論壇融合不可錯過的迷你庫測試框架實例教程為你詳細(xì)解讀請求頭的具體含意解析的庫如果要用前端框架,開發(fā)流程是怎樣的與有什么區(qū)別正確使用的方法是什么流程圖插件小如何讓元素只能輸入純文本前端技術(shù)中 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfront...

    solocoder 評論0 收藏0
  • []學(xué)習(xí)如何去學(xué)習(xí) JavaScript - 5 個你應(yīng)該如何花在學(xué)習(xí) JS 上時間的建議

    摘要:擁抱異步編程縱觀發(fā)展史也可以說成開發(fā)的發(fā)展史,你會發(fā)現(xiàn)異步徹底改變了這場游戲。可以這么說,異步編程已成為開發(fā)的根基。這也是你應(yīng)盡早在上投入大量時間的一處核心知識點,這其中包含和等重要概念。這也是最突出的一項貢獻(xiàn)。 原文地址:Medium - Learning How to Learn JavaScript. 5 recommendations on how you should spend ...

    wanglu1209 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<