国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React 應(yīng)用設(shè)計(jì)之道 - curry 化妙用

LinkedME2016 / 2254人閱讀

摘要:右側(cè)展現(xiàn)對(duì)應(yīng)產(chǎn)品。我們使用命名為的對(duì)象表示過濾條件信息,如下此數(shù)據(jù)需要在組件中進(jìn)行維護(hù)。因?yàn)榻M件的子組件和都將依賴這項(xiàng)數(shù)據(jù)狀態(tài)?;瘧?yīng)用再回到之前的場(chǎng)景,我們?cè)O(shè)計(jì)化函數(shù),進(jìn)一步可以簡(jiǎn)化為對(duì)于的偏應(yīng)用即上面提到的相信大家已經(jīng)理解了這么做的好處。

使用 React 開發(fā)應(yīng)用,給予了前端工程師無限“組合拼裝”快感。但在此基礎(chǔ)上,組件如何劃分,數(shù)據(jù)如何流轉(zhuǎn)等應(yīng)用設(shè)計(jì)都決定了代碼層面的美感和強(qiáng)健性。

同時(shí),在 React 世界里提到 curry 化,也許很多開發(fā)者會(huì)第一時(shí)間反應(yīng)出 React-redux 庫的 connect 方法。然而,如果僅僅機(jī)械化地停留于此,而沒有更多靈活地應(yīng)用,是非常可惜的。

這篇文章以一個(gè)真實(shí)場(chǎng)景為基礎(chǔ),從細(xì)節(jié)出發(fā),分析 curry 化如何化簡(jiǎn)為繁,更優(yōu)雅地實(shí)現(xiàn)需求。

場(chǎng)景介紹

需求場(chǎng)景為一個(gè)賣食品的電商網(wǎng)站,左側(cè)部分為商品篩選欄目,用戶可以根據(jù):價(jià)格區(qū)間、商品年限、商品品牌進(jìn)行過濾。右側(cè)展現(xiàn)對(duì)應(yīng)產(chǎn)品。如下圖:

作為 React 開發(fā)者,我們知道 React 是組件化的,第一步將考慮根據(jù) UE 圖,進(jìn)行組件拆分。這個(gè)過程比較簡(jiǎn)單直觀,我們對(duì)拆分結(jié)果用下圖表示:

對(duì)應(yīng)代碼為:


    
        
        
        
    
    

初級(jí)實(shí)現(xiàn)

React 是基于數(shù)據(jù)狀態(tài)的,緊接著第二步就要考慮應(yīng)用狀態(tài)。商品展現(xiàn)結(jié)果數(shù)據(jù)我們暫時(shí)不需要關(guān)心。這里主要考慮應(yīng)用最重要的狀態(tài),即過濾條件信息

我們使用命名為 filterSelections 的 JavaScript 對(duì)象表示過濾條件信息,如下:

filterSelections = {
  price: ...,
  ages: ...,
  brands: ...,
}

此數(shù)據(jù)需要在 Products 組件中進(jìn)行維護(hù)。因?yàn)?Products 組件的子組件 Filters 和 ProductResults 都將依賴這項(xiàng)數(shù)據(jù)狀態(tài)。

Filters 組件通過 prop 接收 filterSelections 狀態(tài),并拆解傳遞給它的三項(xiàng)篩選子組件:

class Filters extends React.Component {
  render() {
    return (
      
); }; }

同樣地,ProductResults 組件也通過 prop 接收 filterSelections 狀態(tài),進(jìn)行相應(yīng)產(chǎn)品的展示。

對(duì)于 Filters 組件,它一定不僅僅是接收 filterSelections 數(shù)據(jù)而已,同樣也需要對(duì)此項(xiàng)數(shù)據(jù)進(jìn)行更新。為此,我們?cè)?Products 組件中設(shè)計(jì)相應(yīng)的 handler 函數(shù),對(duì)過濾信息進(jìn)行更新,命名為 updateFilters,并將此處理函數(shù)作為 prop 下發(fā)給 Filters 組件:

class Products extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      filterSelections: {
        price: someInitialValue,
        ages: someInitialValue,
        brands: someInitialValue,
      }
    }
  }

  updateFilters = (newSelections) => {
    this.setState({
      filterSelections: newSelections
    })
  };

  render() {
    return(
      
); } }

注意這里我們對(duì) this 綁定方式。有興趣的讀者可以參考我的另一篇文章:從 React 綁定 this,看 JS 語言發(fā)展和框架設(shè)計(jì)。

作為 Filters 組件,同樣也要對(duì)處理函數(shù)進(jìn)行進(jìn)一步拆分和分發(fā):

class Filters extends React.Component {
  updatePriceFilter = (newValue) => {
    this.props.selectionsChanged({
      ...this.props.filterSelections,
      price: newValue
    })
  };

  updateAgeFilter = (newValue) => {
    this.props.selectionsChanged({
      ...this.props.filterSelections,
      ages: newValue
    })
  };

  updateBrandFilter = (newValue) => {
    this.props.selectionsChanged({
      ...this.props.filterSelections,
      brands: newValue
    })
  };
  
  render() {
    return (
      
); }; }

我們根據(jù) selectionsChanged 函數(shù),通過傳遞不同類型參數(shù),設(shè)計(jì)出 updatePriceFilter、updateAgeFilter、updateBrandFilter 三個(gè)方法,分別傳遞給 PriceFilter、AgeFilter、BrandFilter 三個(gè)組件。

這樣的做法非常直接,然而運(yùn)行良好。但是在 Filters 組件中,多了很多函數(shù),且這些函數(shù)看上去做著相同的邏輯。如果將來又多出了一個(gè)或多個(gè)過濾條件,那么同樣也要多出同等數(shù)量的“雙胞胎”函數(shù)。這顯然不夠優(yōu)雅。

currying 是什么

在分析更加優(yōu)雅的解決方案之前,我們先簡(jiǎn)要了解一下 curry 化是什么。curry 化事實(shí)上是一種變形,它將一個(gè)函數(shù) f 變形為 f",f" 的參數(shù)接收原本函數(shù) f 的參數(shù),同時(shí)返回一個(gè)新的函數(shù) f"",f"" 接收剩余的參數(shù)并返回函數(shù) f 的計(jì)算結(jié)果。

這么描述無疑是抽象的,我們還是通過代碼來理解。這是一個(gè)簡(jiǎn)單的求和函數(shù):

add = (x, y) => x + y;

curried 之后:

curriedAdd = (x) => {
  return (y) => {
    return x + y;
  }
}
    

所以,當(dāng)執(zhí)行 curriedAdd(1)(2) 之后,得到結(jié)果 3,curriedAdd(x) 函數(shù)有一個(gè)名字叫 partial application,curriedAdd 函數(shù)只需要原本 add(X, y) 函數(shù)的一部分參數(shù)。

Currying a regular function let’s us perform partial application on it.
curry 化應(yīng)用

再回到之前的場(chǎng)景,我們?cè)O(shè)計(jì) curry 化函數(shù):updateSelections,

updateSelections = (selectionType) => {
  return (newValue) => {
    this.props.selectionsChanged({
      ...this.props.filterSelections,
      [selectionType]: newValue,
    });
  }
};

進(jìn)一步可以簡(jiǎn)化為:

updateSelections = (selectionType) => (newValue) => {
   this.props.selectionsChanged({
      ...this.props.filterSelections,
      [selectionType]: newValue,
   })
};

對(duì)于 updateSelections 的偏應(yīng)用(即上面提到的 partial application):

updateSelections("ages");
updateSelections("brands");
updateSelections("price");

相信大家已經(jīng)理解了這么做的好處。這樣一來,我們的 Filters 組件完整為:

class Filters extends React.Component {
  
  updateSelections = (selectionType) => {
    return (newValue) => {
      this.props.selectionsChanged({
        ...this.props.selections,
        [selectionType]: newValue,  // new ES6 Syntax!! :)
      });
    }
  };

  render() {
    return (
      
); }; }

當(dāng)然,currying 并不是解決上述問題的唯一方案。我們?cè)賮砹私庖环N方法,進(jìn)行對(duì)比消化,updateSelections 函數(shù) uncurried 版本:

updateSelections = (selectionType, newValue) => {
  this.props.updateFilters({
    ...this.props.filterSelections,
    [selectionType]: newValue,
  });
}

這樣的設(shè)計(jì)使得每一個(gè) Filter 組件:PriceFilter、AgeFilter、BrandFilter 都要調(diào)用 updateSelections 函數(shù)本身,并且要求組件本身感知 filterSelections 的屬性名,以進(jìn)行相應(yīng)屬性的更新。這就是一種耦合,完整實(shí)現(xiàn):

class Filters extends React.Component {

      updateSelections = (selectionType, newValue) => {
        this.props.selectionsChanged({
          ...this.props.filterSelections,
          [selectionType]: newValue, 
        });
      };
    
      render() {
        return (
          <>
             this.updateSelections("price", value)} 
            />
             this.updateSelections("ages", value)} 
            />
             this.updateSelections("brands", value)} 
            />
          
        );
      };
    }

其實(shí)我認(rèn)為,在這種場(chǎng)景下,關(guān)于兩種方案的選擇,可以根據(jù)開發(fā)者的偏好來決定。

總結(jié)

這篇文章內(nèi)容較為基礎(chǔ),但從細(xì)節(jié)入手,展現(xiàn)了 React 開發(fā)編寫和函數(shù)式理念相結(jié)合的魅力。文章譯自這里,部分內(nèi)容有所改動(dòng)。

廣告時(shí)間:
如果你對(duì)前端發(fā)展,尤其對(duì) React 技術(shù)棧感興趣:我的新書中,也許有你想看到的內(nèi)容。關(guān)注作者 Lucas HC,新書出版將會(huì)有送書活動(dòng)。

Happy Coding!

PS: 作者?Github倉庫?和?知乎問答鏈接?歡迎各種形式交流!

我的其他幾篇關(guān)于React技術(shù)棧的文章:

從setState promise化的探討 體會(huì)React團(tuán)隊(duì)設(shè)計(jì)思想

從setState promise化的探討 體會(huì)React團(tuán)隊(duì)設(shè)計(jì)思想

通過實(shí)例,學(xué)習(xí)編寫 React 組件的“最佳實(shí)踐”

React 組件設(shè)計(jì)和分解思考

從 React 綁定 this,看 JS 語言發(fā)展和框架設(shè)計(jì)

做出Uber移動(dòng)網(wǎng)頁版還不夠 極致性能打造才見真章**

React+Redux打造“NEWS EARLY”單頁應(yīng)用 一個(gè)項(xiàng)目理解最前沿技術(shù)棧真諦**

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/52217.html

相關(guān)文章

  • React 應(yīng)用設(shè)計(jì)之道 - curry 妙用

    摘要:右側(cè)展現(xiàn)對(duì)應(yīng)產(chǎn)品。我們使用命名為的對(duì)象表示過濾條件信息,如下此數(shù)據(jù)需要在組件中進(jìn)行維護(hù)。因?yàn)榻M件的子組件和都將依賴這項(xiàng)數(shù)據(jù)狀態(tài)?;瘧?yīng)用再回到之前的場(chǎng)景,我們?cè)O(shè)計(jì)化函數(shù),進(jìn)一步可以簡(jiǎn)化為對(duì)于的偏應(yīng)用即上面提到的相信大家已經(jīng)理解了這么做的好處。 showImg(https://segmentfault.com/img/remote/1460000014458612?w=1240&h=663...

    sewerganger 評(píng)論0 收藏0
  • React 設(shè)計(jì)模式和場(chǎng)景分析

    摘要:這一周連續(xù)發(fā)表了兩篇關(guān)于的文章組件復(fù)用那些事兒實(shí)現(xiàn)按需加載輪子應(yīng)用設(shè)計(jì)之道化妙用其中涉及到組件復(fù)用輪子設(shè)計(jì)相關(guān)話題,并配合相關(guān)場(chǎng)景實(shí)例進(jìn)行了分析。 showImg(https://segmentfault.com/img/remote/1460000014482098); 這一周連續(xù)發(fā)表了兩篇關(guān)于 React 的文章: 組件復(fù)用那些事兒 - React 實(shí)現(xiàn)按需加載輪子 React ...

    avwu 評(píng)論0 收藏0
  • React 設(shè)計(jì)模式和場(chǎng)景分析

    摘要:這一周連續(xù)發(fā)表了兩篇關(guān)于的文章組件復(fù)用那些事兒實(shí)現(xiàn)按需加載輪子應(yīng)用設(shè)計(jì)之道化妙用其中涉及到組件復(fù)用輪子設(shè)計(jì)相關(guān)話題,并配合相關(guān)場(chǎng)景實(shí)例進(jìn)行了分析。 showImg(https://segmentfault.com/img/remote/1460000014482098); 這一周連續(xù)發(fā)表了兩篇關(guān)于 React 的文章: 組件復(fù)用那些事兒 - React 實(shí)現(xiàn)按需加載輪子 React ...

    sshe 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<