<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        分解React組件的幾種進階方法

        來源:懂視網 責編:小采 時間:2020-11-27 20:03:31
        文檔

        分解React組件的幾種進階方法

        分解React組件的幾種進階方法:React 組件魔力無窮,同時靈活性超強。我們可以在組件的設計上,玩轉出很多花樣。但是保證組件的Single responsibility principle: 單一原則非常重要,它可以使得我們的組件更簡單、更方便維護,更重要的是使得組件更加具有復用性。本文主要和大家分享分解R
        推薦度:
        導讀分解React組件的幾種進階方法:React 組件魔力無窮,同時靈活性超強。我們可以在組件的設計上,玩轉出很多花樣。但是保證組件的Single responsibility principle: 單一原則非常重要,它可以使得我們的組件更簡單、更方便維護,更重要的是使得組件更加具有復用性。本文主要和大家分享分解R

        React 組件魔力無窮,同時靈活性超強。我們可以在組件的設計上,玩轉出很多花樣。但是保證組件的Single responsibility principle: 單一原則非常重要,它可以使得我們的組件更簡單、更方便維護,更重要的是使得組件更加具有復用性。本文主要和大家分享分解React 組件的幾種進階方法,希望能幫助到大家。

        但是,如何對一個功能復雜且臃腫的 React 組件進行分解,也許并不是一件簡單的事情。本文由淺入深,介紹三個分解 React 組件的方法。

        方法一:切割 render() 方法

        這是一個最容易想到的方法:當一個組件渲染了很多元素時,就需要嘗試分離這些元素的渲染邏輯。最迅速的方式就是切割 render() 方法為多個 sub-render 方法。

        看下面的例子會更加直觀:

        class Panel extends React.Component {
         renderHeading() { // ...
         }
        
         renderBody() { // ...
         }
        
         render() { return (
         <div>
         {this.renderHeading()}
         {this.renderBody()}
         </div>
         );
         }
        }

        細心的讀者很快就能發現,其實這并沒有分解組件本身,該 Panel 組件仍然保持有原先的 state, props, 以及 class 方法。

        如何真正地做到減少組件復雜度呢?我們需要創建一些子組件。此時,采用最新版 React 支持并推薦的函數式組件/無狀態組件一定會是一個很好的嘗試:

        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>
         );
         }
        }

        同之前的方式相比,這個微妙的改進是革命性的。

        我們新建了兩個單元組件:PanelHeader 和 PanelBody。這樣帶來了測試的便利,我們可以直接分離測試不同的組件。同時,借助于 React 新的算法引擎 React Fiber,兩個單元組件在渲染的效率上,樂觀地預計會有較大幅度的提升。

        方法二:模版化組件

        回到問題的起點,為什么一個組件會變的臃腫而復雜呢?其一是渲染元素較多且嵌套,另外就是組件內部變化較多,或者存在多種 configurations 的情況。

        此時,我們便可以將組件改造為模版:父組件類似一個模版,只專注于各種 configurations。

        還是要舉例來說,這樣理解起來更加清晰。

        比如我們有一個 Comment 組件,這個組件存在多種行為或事件。

        同時組件所展現的信息根據用戶的身份不同而有所變化:

      1. 用戶是否是此 comment 的作者;

      2. 此 comment 是否被正確保存;

      3. 各種權限不同

      4. 等等......

      5. 都會引起這個組件的不同展示行為。

        這時候,與其把所有的邏輯混淆在一起,也許更好的做法是利用 React 可以傳遞 React element 的特性,我們將 React element 進行組件間傳遞,這樣就更加像一個強大的模版:

        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>
         ...
         )
         }
        }

        此時,我們真正的 Comment 組件組織為:

        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} />;
         }
        }

        metadata 和 actions 其實就是在特定情況下需要渲染的 React element。

        比如:

      6. 如果 this.props.publishTime 存在,metadata 就是 <PublishTime time={this.props.publishTime} />;

      7. 反之則為 <span>Saving...</span>。

      8. 如果用戶已經登陸,則需要渲染(即actions值為) <LikeAction /> 和 <ReplyAction />;

      9. 如果是作者本身,需要渲染的內容就要加入 <DeleteAction />。

      10. 方法三:高階組件

        在實際開發當中,組件經常會被其他需求所污染。

        想象這樣一個場景:我們想統計頁面中所有鏈接的點擊信息。在鏈接點擊時,發送統計請求,同時這條請求需要包含此頁面 document 的 id 值。

        常見的做法是在 Document 組件的生命周期函數 componentDidMount 和 componentWillUnmount 增加代碼邏輯:

        class Document extends React.Component {
         componentDidMount() {
         ReactDOM.findDOMNode(this).addEventListener('click', this.onClick);
         }
        
         componentWillUnmount() {
         ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick);
         }
        
         onClick = (e) => { // Naive check for <a> elements if (e.target.tagName === 'A') { 
         sendAnalytics('link clicked', { // Specific information to be sent
         documentId: this.props.documentId 
         });
         }
         };
        
         render() { // ...
         }
        }

        這么做的幾個問題在于:

      11. 相關組件 Document 除了自身的主要邏輯:顯示主頁面之外,多了其他統計邏輯;

      12. 如果 Document 組件的生命周期函數中,還存在其他邏輯,那么這個組件就會變的更加含糊不合理;

      13. 統計邏輯代碼無法復用;

      14. 組件重構、維護都會變的更加困難。

      15. 為了解決這個問題,我們提出了高階組件這個概念: higher-order components (HOCs)。不去晦澀地解釋這個名詞,我們來直接看看使用高階組件如何來重構上面的代碼:

        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) => { // Naive check for <a> elements if (e.target.tagName === 'A') { 
         const data = mapPropsToData ? mapPropsToData(this.props) : {};
         sendAnalytics('link clicked', data);
         }
         };
        
         render() { // Simply render the WrappedComponent with all props return <WrappedComponent {...this.props} />;
         }
         }
         ...
        }

        需要注意的是,withLinkAnalytics 函數并不會去改變 WrappedComponent 組件本身,更不會去改變 WrappedComponent 組件的行為。而是返回了一個被包裹的新組件。實際用法為:

        class Document extends React.Component {
         render() { // ...
         }
        }
        
        export default withLinkAnalytics((props) => ({
         documentId: props.documentId
        }), Document);

        這樣一來,Document 組件仍然只需關心自己該關心的部分,而 withLinkAnalytics 賦予了復用統計邏輯的能力。

        高階組件的存在,完美展示了 React 天生的復合(compositional)能力,在 React 社區當中,react-redux,styled-components,react-intl 等都普遍采用了這個方式。值得一提的是,recompose 類庫又利用高階組件,并發揚光大,做到了“腦洞大開”的事情。

        React 及其周邊社區的崛起,讓函數式編程風靡一時,受到追捧。其中關于 decomposing 和 composing 的思想,我認為非常值得學習。同時,對開發設計的一個建議是,一般情況下,不要猶豫將你的組件拆分的更小、更單一,因為這樣能換來強健和復用。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        分解React組件的幾種進階方法

        分解React組件的幾種進階方法:React 組件魔力無窮,同時靈活性超強。我們可以在組件的設計上,玩轉出很多花樣。但是保證組件的Single responsibility principle: 單一原則非常重要,它可以使得我們的組件更簡單、更方便維護,更重要的是使得組件更加具有復用性。本文主要和大家分享分解R
        推薦度:
        標簽: 方法 分解 的方法
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲JIZZJIZZ中国少妇中文| 亚洲中文字幕无码中文字在线| 亚洲美女大bbbbbbbbb| 花蝴蝶免费视频在线观看高清版| 久久这里只精品国产免费10| 亚洲香蕉网久久综合影视| 中国一级特黄高清免费的大片中国一级黄色片| 国产成人免费ā片在线观看| 黄色免费在线网址| 亚洲中文字幕伊人久久无码| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 国产精品亚洲综合专区片高清久久久 | 高潮毛片无遮挡高清免费| 免费一级毛片在级播放| 一区二区三区AV高清免费波多| 2048亚洲精品国产| 无码A级毛片免费视频内谢| 日本高清免费网站| 免费无码国产在线观国内自拍中文字幕 | 日韩免费高清大片在线| 国产乱子伦片免费观看中字| 国产精品1024在线永久免费| 日韩精品视频免费在线观看| 深夜特黄a级毛片免费播放| 国产国拍亚洲精品福利| 222www免费视频| 亚洲精品国产字幕久久不卡| 99在线免费观看视频| 国产91在线|亚洲| yy6080亚洲一级理论| 免费人成黄页在线观看日本| 亚洲一区免费在线观看| 亚洲人成电影在线播放| 99热这里有免费国产精品| 99亚洲男女激情在线观看| 亚洲欧洲无码AV电影在线观看| 99在线视频免费观看视频| 亚洲成人一级电影| 免费一级一片一毛片| 免费人妻无码不卡中文字幕系| 亚洲精品乱码久久久久久V |