未加星标

Flattening Deep Hierarchies of Components

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

Flattening Deep Hierarchies of Components

Components are an awesome tool for building interfaces. They allow you to break down the UI into distinct reusable elements. These can then be composed to build complex applications in a more sustainable way.

Each component has its own well defined public API. In React this is defined by the component props. Whereas in Angular 2, it's inputs and outputs. The choice of this API can have a drastic impact on your application. Consider the following example of a Card component.


Flattening Deep Hierarchies of Components

It has one job: display an image with a title. You might be tempted to build it out such that it abstracts away all the logic for its constituent parts: image, title, etc.

<Card img={ 'img/rotary-phone.png' } title={ 'Choosing the Right Antique Rotary Phone for You.' } contentPaddingX={ 2 } contentPaddingY={ 2 } />

As the complexity of your app grows you might introduce other scenarios for this Card component. The card should now be able to display a caption or an icon with a click action?


Flattening Deep Hierarchies of Components
// Card with title and caption <Card img={ 'img/rotary-phone.png' } title={ 'Choosing the Right Antique Rotary Phone for You.' } caption={ '21 hours ago' } contentPaddingX={ 2 } contentPaddingY={ 2 } /> // Card with title, caption and icon <Card img={ 'img/rotary-phone.png' } title={ 'Choosing the Right Antique Rotary Phone for You.' } caption={ '21 hours ago' } contentPaddingX={ 2 } contentPaddingY={ 2 } icon={ 'add-to-cart' } iconAction={ addToCart } />

You now have to add more logic to this component. It has to account for all these permutations and combinations of its constituent parts. You can probably see the issue here. What started as a simple component has bloated into something that is hard to maintain, hard to test and not at all flexible.

We can write better components by adopting an approach similar to function composition.

Function Composition

Function composition is the act of combining simple functions to build more complicated ones.

f(g(h(x)) = compose(f, g, h)(x);

Consider the following example:

function complexFunction(x) { const a = 2 * x; const b = a + 5; const c = b / 2; const d = c * 12; return d; }

Here the complexFunction is very similar to what we attempted with the Card component. This one function is trying to do too much. We can achieve the same behaviour using compose instead:

function add(r, x) { return x + r; } function multiply(r, x) { return x * r; } function divideBy(r, x) { return x / r; } const complexFunction = compose( multiply(12), divideBy(2), compose(add(5), multiply(2)) );

Here we have broken out the various math operations into pure functions. We can now compose these functions to create the complexFunction or any other type of combination.

Instead of having one massive function which accounts for various scenarios we have created a toolbox of smaller single responsibility functions. Testing this is much easier because you don't have to account for the different scenarios.

Applying Function Composition to Components

Let us apply this same principle to the Card component. We start by breaking out its sub-components:

Media : a generic image component Body : body container for the card Title : the card title Caption : card caption Icon : a generic icon component
Flattening Deep Hierarchies of Components

Now, instead of passing all data into the Card component we instead use children (React) or ng-content (known as projection in Angular 2, and transclusion in Angular 1). The card on the right will now look something like this:

// Card with title, caption and icon <Card> <Media source={ 'img/rotary-phone.png' } /> <Body paddingX={ 2 } paddingY={ 2 }> <Title> Choosing the Right Antique Rotary Phone for You. </Title> <Caption> { '21 hours ago' } <Icon name="add-to-cart" handleClick={ addToCart } /> </Caption> </Body> </Card>

This is much better. Let's observe some benefits:

The Card is now agnostic to what content goes inside it. This flattens our component tree. There is less data that needs to be passed through the various levels of the component hierarchy.

Each component has one responsibility which makes testing trivial.

We gain a lot more flexibility. Developers can compose different types of cards or even create new ones since they have full control over the content of the card.

Highly Reusable Components

We can improve this further. You might notice that Body , Title and Caption all seem like specialized components. They are somewhat tied to the Card component. We can instead replace them with a few generic components:

Block : a generic box with visual styling Heading : a heading component with size based on a font scale Button : a generic button component with various styles

Notice the muted property for Heading . Instead of creating a Caption component we are reusing the Heading component and simply passing in a boolean with applies the muted colours.

// Card with title, caption and icon <Card> <Media source={ 'img/rotary-phone.png' } /> <Block paddingX={ 2 } paddingY={ 2 }> <Heading size={ 2 }> Choosing the Right Antique Rotary Phone for You. </Heading> <Block> <Heading size={ 3 } muted>21 hours ago</Heading> <Button style="clear" handleClick={ addToCart }> <Icon name="add-to-cart" /> </Button> </Block> </Block> </Card>

And here is the final version in Angular 2:

<!-- Card with title, caption and icon --> <Card> <Media [source]="'img/rotary-phone.png'" }></Media> <Block paddingX="2" paddingY="2"> <Heading size="2"> Choosing the Right Antique Rotary Phone for You. </Heading> <Block> <Heading size="3" muted>21 hours ago</Heading> <Button style="clear" (handleClick)="addToCart($event)"> <Icon name="add-to-cart" /> </Button> </Block> </Block> </Card>

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: ReactHead
分页:12
转载请注明
本文标题:Flattening Deep Hierarchies of Components
本站链接:http://www.codesec.net/view/484694.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(20)