React進(jìn)階學(xué)習(xí)之組件的解耦之道
前言
眾所周知,React中的組件非常的靈活可擴(kuò)展,不過(guò)隨著業(yè)務(wù)復(fù)雜度的增加和許多外部工具庫(kù)的引入,組件往往也會(huì)顯得浮腫,接下來(lái)我們就一起來(lái)看看常見(jiàn)的幾種,遵循單一職責(zé)原則的,組件分割與解耦的方法,話(huà)不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹:
一、分割 render 函數(shù)
當(dāng)一個(gè)組件渲染的內(nèi)容較多時(shí),有一個(gè)快速并且通用的方法是創(chuàng)建sub-render函數(shù)來(lái)簡(jiǎn)化原來(lái)龐大的 render
class Panel extends React.Component {
renderHeading() {
// ...
}
renderBody() {
// ...
}
render() {
return (
<div>
{this.renderHeading()}
{this.renderBody()}
</div>
);
}
}
為了再次簡(jiǎn)化sub-render函數(shù),我們還可以采用Functional Components寫(xiě)法,這種方式生成了更小的處理單元,且更有利于測(cè)試
const PanelHeader = (props) => (
// ...
);
const PanelBody = (props) => (
// ...
);
class Panel extends React.Component {
render() {
return (
<div>
// Nice and explicit about which props are used
<PanelHeader title={this.props.title}/>
<PanelBody content={this.props.content}/>
</div>
);
}
}
二、用 props 傳遞元素
如果一個(gè)組件的狀態(tài)或配置較多,我們可以運(yùn)用props傳遞元素而不僅是數(shù)據(jù),比如再聲明一個(gè)組件,使其中的父組件只專(zhuān)注于配置
class CommentTemplate extends React.Component {
static propTypes = {
// Declare slots as type node
metadata: PropTypes.node,
actions: PropTypes.node,
};
render() {
return (
<div>
<CommentHeading>
<Avatar user={...}/>
// Slot for metadata
<span>{this.props.metadata}</span>
</CommentHeading>
<CommentBody/>
<CommentFooter>
<Timestamp time={...}/>
// Slot for actions
<span>{this.props.actions}</span>
</CommentFooter>
</div>
);
}
}
父組件
class Comment extends React.Component {
render() {
const metadata = this.props.publishTime ?
<PublishTime time={this.props.publishTime} /> :
<span>Saving...</span>;
const actions = [];
if (this.props.isSignedIn) {
actions.push(<LikeAction />);
actions.push(<ReplyAction />);
}
if (this.props.isAuthor) {
actions.push(<DeleteAction />);
}
return <CommentTemplate metadata={metadata} actions={actions} />;
}
}
三、使用高階組件
實(shí)現(xiàn)點(diǎn)擊某組件的超鏈接,發(fā)送該組件的 ID,我們大多的解決方法可能如下
class Document extends React.Component {
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('click', this.onClick);
}
componentWillUnmount() {
ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick);
}
onClick = (e) => {
if (e.target.tagName === 'A') { // Naive check for <a> elements
sendAnalytics('link clicked', {
documentId: this.props.documentId // Specific information to be sent
});
}
};
render() {
// ...
}
}
然而它卻存在代碼不能復(fù)用,組件重構(gòu)困難等問(wèn)題
我們可以使用高階組件來(lái)解決這些問(wèn)題,顧名思義,高階組件就是一個(gè)函數(shù),傳給它一個(gè)組件,它返回一個(gè)新的組件
function withLinkAnalytics(mapPropsToData, WrappedComponent) {
class LinkAnalyticsWrapper extends React.Component {
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('click', this.onClick);
}
componentWillUnmount() {
ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick);
}
onClick = (e) => {
if (e.target.tagName === 'A') { // Naive check for <a> elements
const data = mapPropsToData ? mapPropsToData(this.props) : {};
sendAnalytics('link clicked', data);
}
};
render() {
// Simply render the WrappedComponent with all props
return <WrappedComponent {...this.props} />;
}
}
return LinkAnalyticsWrapper;
}
簡(jiǎn)化代碼如下
class Document extends React.Component {
render() {
// ...
}
}
export default withLinkAnalytics((props) => ({
documentId: props.documentId
}), Document);
總結(jié)
以上 3 個(gè) React 組件的解耦重構(gòu)方法都可以直接拿來(lái)運(yùn)用,最開(kāi)始可能會(huì)覺(jué)得有點(diǎn)棘手,但是沒(méi)關(guān)系,只要堅(jiān)持下來(lái),你就會(huì)寫(xiě)出更強(qiáng)壯和可復(fù)用的代碼。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
React?less?實(shí)現(xiàn)縱橫柱狀圖示例詳解
這篇文章主要介紹了React?less?實(shí)現(xiàn)縱橫柱狀圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
react學(xué)習(xí)筆記之state以及setState的使用
這篇文章主要介紹了react學(xué)習(xí)筆記之state以及setState的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
redux功能強(qiáng)大的Middleware中間件使用學(xué)習(xí)
這篇文章主要為大家介紹了redux功能強(qiáng)大的Middleware中間件使用學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
React中用@符號(hào)編寫(xiě)文件路徑實(shí)現(xiàn)方法介紹
在Vue中,我們導(dǎo)入文件時(shí),文件路徑中可以使用@符號(hào)指代src目錄,極大的簡(jiǎn)化了我們對(duì)路徑的書(shū)寫(xiě)。但是react中,要想實(shí)現(xiàn)這種方式書(shū)寫(xiě)文件路徑,需要寫(xiě)配置文件來(lái)實(shí)現(xiàn)2022-09-09
react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist
這篇文章主要為大家詳細(xì)介紹了react用Redux中央倉(cāng)庫(kù)實(shí)現(xiàn)一個(gè)todolist,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09

