我refactorizing龐大的系統工程,其中陣營高階元素 - 一個能走多遠與傳遞道具
- 一些部件看起來非常相似
- 有文件的文件的looots(非常高的水平組件VS文件造粒)
我想過和尋找方法來處理這個問題在這裏和那裏,發現這個偉大的文章有關高階組件(HOC) - 基本上是組件包裝另一個組件。
https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e#.8vr464t20
我現在給你(A)三分之二八個類似的組件類型,我需要處理,比(B)的例如我會貼上我想出了代碼將這八個文件合併爲一個。最後,(C)將粘貼該統一組件的使用示例。
我會盡量保持一致,並且命名不會被域驅動(我不能在這裏發佈項目細節),但下面不同的代碼片段中的相同名稱將始終指向相同的組件和數據。否則我會指出它。
(A) - 類似的組件類型
1塔巴 - 簡單的一
export default class TabA extends Component {
render() {
return (
<PageWrapper>
<Grid>
<GridItem xsSize="3">
<SmartComponent something={this.props.something }/>
</GridItem>
<GridItem xsSize="9">
<Tabs
permalink = { this.props.permalink }
history={ this.props.history }
activeTab={ Paths.somePath }
/>
<TabAContent
data={ this.props.data }
name={ this.props.name }
someValue={ this.props.someValue }
/>
</GridItem>
</Grid>
</PageWrapper>
);
}
}
注意SomeComponentA不採取任何的孩子也有。這裏沒有任何條件的渲染。
2.塔布 - 更復雜的一個
同樣在這裏,請注意renderSomeData方法有條件地呈現SmartComponentToBeConditionallyRendered也SomeComponentB對待兒童從道具。
export default class TabB extends Component {
renderSomeData() {
let someData = {
header: "Header text",
searchPlaceHolder: 'Search (name)',
buttonCaption: 'button caption'
};
return (
<SmartComponentToBeConditionallyRendered
type={ 'some_type' }
permalink={ this.props.permalink }
data={ someData }
/>
)
}
render() {
let { data } = this.props;
return (
<div>
<PageWrapper>
<Grid>
<GridItem xsSize="3">
<SmartComponent something={this.props.something}/>
</GridItem>
<GridItem xsSize="9">
<Tabs
permalink = { this.props.permalink }
history = { this.props.history }
activeTab = { Paths.somePage }
/>
<TabBContent data = { data }>
{this.props.children}
</TabBContent>
</GridItem>
</Grid>
</PageWrapper>
{
this.context.hasPermission('somePermission') ?
this.renderSomeData() :
null
}
</div>
)
}
static contextTypes = {
hasPermission: React.PropTypes.func.isRequired
}
}
這8個分量,我一開始寫的 - 它們都代表三種可能性之一。 以上兩圖和可能性C,但C中的差異只是另一個有條件渲染的組件,所以不值得一提,因爲它最終會降低傳遞道具中的更多標誌。 -
這兩個部件上述他們在不同:
- 樣SomeComponentX的 - 代替X的有可能的A,B,而且C,d,E等在每個這八個類似的部件。 SomeComponentX中的每一個也都採用不同的道具。
- 路徑。VALUE_HERE
- 如果SomeComponentX發生在任何的兒童或者不
- 如果他們有條件從renderSomeData方法
- 呈現數據如果是 - 該方法中定義someData變化以及
- 永久
- some_type
(B)我想出了什麼
let availablePartials = {
PartialA: PartialA,
PartialB: PartialB,
PartialC: PartialC
}
export default class GenericTab extends Component {
renderSomeData() {
return (
<SomeData
type = { this.props.type }
permalink = { this.props.permalink }
data = { this.props.someData } //PASSED FROM PROPS NOW
/>
);
}
render() {
let tabContent = React.createElement(
availablePartials[this.props.partialView.name],
this.props.partialView.props,
this.props.renderChildren ? this.props.children : null
);
return (
<div>
<PageWrapper>
<Grid>
<GridItem xsSize="3">
<SmartComponent something = { this.props.permalink }/>
</GridItem>
<GridItem xsSize = "9">
<Tabs
permalink = { this.props.permalink }
history = { this.props.history }
activeTab = { this.props.activeTab }
/>
{ tabContent }
</GridItem>
</Grid>
</PageWrapper>
{
this.context.hasPermission(this.props.requiredPermission) && this.props.dataForSomeDataMethod ?
this.renderSomeData()
: null
}
</div>
)
}
static contextTypes = {
hasPermission: React.PropTypes.func.isRequired
}
};
CityPageTab.propTypes = {
permalink: PropTypes.string,
dataForSomeDataMethod: PropTypes.object,
type: PropTypes.string,
activeTab: PropTypes.string,
renderChildren: PropTypes.bool,
partialView: PropTypes.object,
requiredPermission: PropTypes.string
};
基本上是所有從道具構成。我唯一不喜歡的部分是availablePartials [this.props.partialView.name]。它需要開發者保持availablePartials對象的狀態一致並且糾結一點。不是很好的解決方案,但仍然是最好的我到目前爲止。
(C)新GenericTab使用例
componentThatUseGenericTabRenderMethod() {
let { valueA, valueB, valueC, history } = this.props;
let someData = {
header: 'header text',
searchPlaceHolder: 'Search (name)',
buttonCaption: 'buttonCaption'
}
return (
<GenericTab
partialView = {{
name: 'PartialA',
props: {
A: valueA,
B: valueB,
C: valueC,
history: history,
permalink: this.props.params.permalink
}
}}
permalink = { this.props.params.permalink }
activeTab = { Paths.somePath }
someData = { someData }
type = { 'SOME_TYPE' }
renderChildren = { false }
requiredPermission = { 'some_required_permision' }
/>
);
}
所以這是。用法有點複雜,但我擺脫了七個文件(並且擺脫文件是主要目標,因爲它們太多了),並且將以類似的方式進一步推動它 - 通用文件。 具有通用性的東西 - 使用起來更加困難,但節省了大量空間。
項目利用終極版,所以不要太在意通過道具把樹砍倒。他們總是隻來自一些SmartParentComponent呈現GenericTab
下面是它的外觀在頁面上的可視化。 GenericTab負責渲染Tabs和TabContent部分。 是的,我知道這是很糟糕的解決方案,但我不負責它的體系結構。這裏有很多事情需要重構,所問的僅僅是旅程中的一步。所以請讓我們專注於所問的問題,而不是其他與此代碼錯誤的事情。我知道了。:)
想我可以做的文章出來的,但我真的沒有博客做:)。
請告訴我你的想法,建議升級,處理該問題的不同方式等
您可以加入的是什麼選項卡看起來像一些視覺上的表現?這裏很難理解整個事情,但我已經可以告訴你,你是組件負責渲染很多東西,你應該把它分成幾個較小的組件。 – Pcriulan
嗯,唯一對我來說合理的分割方法是'renderSomeData'。我可以提取它,這是真的。除此之外,我在這裏沒有看到很多可能性。項目很混亂,有很多事情要做。是的,我會嘗試編輯我的問題並添加可視化。 – azrahel
我相信這是有點可能的,當你編輯你的問題我想我可以幫你這麼做 – Pcriulan