1. 程式人生 > >當初要是看了這篇,React高階元件早會了

當初要是看了這篇,React高階元件早會了

概況:

什麼是高階元件?

高階部件是一種用於複用元件邏輯的高階技術,它並不是 React API的一部分,而是從React 演化而來的一種模式。 具體地說,高階元件就是一個接收一個元件並返回另外一個新元件的函式!

這是官方文件說的,我沒有截全,因為後面的解釋會造成誤解,但簡單講高階元件(函式)就好比一個加工廠,同樣的,螢幕、cpu、揚聲器、電池,小米手機工廠組裝完就是小米手機,魅族手機組裝完就是魅族手機,基本材料都是相同的,不同工廠(高階元件)有不同的實現及產出,當然這個工廠(高階元件)也可能是針對某個基本材料的處理。 總之產出的結果擁有了輸入元件不具備的功能,輸入的元件可以是一個元件的例項,也可以是一個元件類,還可以是一個無狀態元件的函式。

解決什麼問題?

隨著專案越來越複雜,開發過程中,多個元件需要某個功能,而且這個功能和頁面並沒有關係,所以也不能簡單的抽取成一個新的元件,但是如果讓同樣的邏輯在各個元件裡各自實現,無疑會導致重複的程式碼。比如頁面有三種彈窗一個有title,一個沒有,一個又有右上角關閉按鈕,除此之外別無它樣,你總不能整好幾個彈窗元件吧,這裡除了tilte,關閉按鈕其他的就可以做為上面說的基本材料。

高階元件總共分為兩大類

  • 代理方式
  1. 操縱prop
  2. 訪問ref(不推薦)
  3. 抽取狀態
  4. 包裝元件
  • 繼承方式
  1. 操縱生命週期
  2. 操縱prop

代理方式之 操縱prop

刪除prop
JavaScript
12345678910 import React from'react'functionHocRemoveProp(WrappedComponent){ returnclassWrappingComPonent extendsReact.Component{  render(){   const{user,...otherProps}=this.props;   returnWrappedComponent{...otherProps}/>  } }}export defaultHocRemoveProp;
增加prop

接下來我把簡化了寫法,把匿名函式去掉,同時換成箭頭函式

JavaScript
1234567891011 import React from'react';constHocAddProp=(WrappedComponentuid)=> classextendsReact.Component{  render(){   constnewProps={    uid,   };   return<WrappedComponent{...this.props} {...newProps} />  } }export defaultHocAddProp;

上面HocRemoveProp高階元件中,所做的事情和輸入元件WrappedComponent功能一樣,只是忽略了名為user的prop。也就是說,如果WrappedComponent能處理名為user的prop,這個高階元件返回的元件則完全無視這個prop。

JavaScript
1 const{user,...otherProps}=this.props;

這是一個利用es6語法技巧,經過上面的語句,otherProps裡面就有this.props中所有的欄位除了user. 假如我們現在不希望某個元件接收user的prop,那麼我們就不要直接使用這個元件,而是把這個元件作為引數傳遞給HocRemoveProp,然後我們把這個函式的返回結果當作元件來使用 兩個高階元件的使用方法:

JavaScript
12 const newComponent=HocRemoveProp(SampleComponent);const newComponent=HocAddProp(SampleComponent,'1111111');

也可以利用decorator語法糖這樣使用

JavaScript
123456 import React,{Component}from'React';@HocRemovePropclassSampleComponentextendsComponent{render(){}}export defaultSampleComponent;

代理方式之 抽取狀態

將所有的狀態的管理交給外面的容器元件,這個模式就是 抽取狀態 外面的容器就是這個高階元件

JavaScript
1234567891011121314151617181920212223 constHocContainer=(WrappedComponent)=> classextendsReact.Component{  constructor(props){   super(props)   this.state={    name:''   }  }  onNameChange=(event)=>{   this.setState({    name:event.target.value   })  }  render(){   constnewProps={    name:{     value:this.state.name,     onChange:this.onNameChange    }   }   return<WrappedComponent{...this.props}{...newProps}/>  } }
JavaScript
123456 @HocContainerclassSampleComponent extendsReact.Component{ render(){  return<input name="name"{...this.props.name}/> }}

這樣當我們在使用這個已經被包裹的input元件(SampleComponent)時候 它的值就被放在了HocContainer高階元件中,當很多這樣的input元件都用這個HocContainer高階元件時,那麼它們的值都將儲存在這個HocContainer高階元件中

代理方式之 包裝元件

JavaScript
12345678910 constHocStyleComponent=(WrappedComponent,style)=> classextendsReact.Component{  render(){   return(    <div style={style}>     <WrappedComponent{...this.props}{...newProps}/>    </div>   )  } }

這樣使用

JavaScript
123 import HocStyleComponent from './HocStyleComponent';constcolorSytle={color:'#ff5555'}const newComponent=HocStyleComponent(SampleComponent,colorSytle);

-代理方式的生命週期的過程類似於堆疊呼叫:

JavaScript
1 didmount>HOC didmount>(HOCs didmount)>(HOCs will unmount)>HOC will unmount>unmount

在說繼承方式之前先看一個例子

JavaScript
123456 constMyContainer=(WrappedComponent)=> classextendsWrappedComponent{  render(){   returnsuper.render();  } }

這個例子很簡單,相當於把WrappedComponent元件的render方法,

通過super.render()方法吐到了MyContainer 中,可以順序呼叫。

繼承方式的生命週期的過程類似佇列呼叫:

JavaScript
1 didmount>HOC didmount>(HOCs didmount)>will unmount>HOC will unmount>(HOCs will unmount)

1.代理方式下WrappedComponent會經歷一個完整的生命週期,產生的新元件和引數元件是兩個不同的元件,一次渲染,兩個元件都會經歷各自的生命週期,

2.而在繼承方式下,產生的新元件和引數元件合二為一,super.render只是生命週期中的函式,變成一個生命週期。

來看下面的例子你就會明白了。

繼承方式之 操縱生命週期(渲染劫持)

首先建立一個高階,在建立一個使用高階元件的元件,也就是是輸入元件,最後我在改變這個輸入元件props

JavaScript
12345678910 import*asReact from'react';constHocComponent=(WrappedComponent)=> classMyContainerextendsWrappedComponent{  render(){   if(this.props.time&&this.state.success){    returnsuper.render()   }   return<div>倒計時完成了...</div>  } }

這個高階元件會直接讀取輸入元件中的props,state,然後控制了輸入元件的render展示 只有在props.time和state.success同時為真的時候才會展示

JavaScript
123456789101112131415 import*asReact from'react';import HocComponent from'./HocComponent'@HocComponentclassDemoComponent extendsReact.Component{ constructor(props){  super(props); this.state={  success:true, };} render(){  return <div>我是一個元件</div> }}export defaultDemoComponent;

然後呼叫,遞減time數值直到變為0最後頁面的效果就是,當然他不是迴圈的。先展示”我是一個元件“,我設定了兩秒,之後展示”倒計時完成“

由此可以看出高階元件也可以控制state

但是最好要限制這樣做,可能會讓WrappedComponent元件內部狀態變得一團糟。建議可以通過重新命名state,以防止混淆。

繼承方式之 操縱prop

相關推薦

當初要是React高階元件

概況: 什麼是高階元件? 高階部件是一種用於複用元件邏輯的高階技術,它並不是 React API的一部分,而是從React 演化而來的一種模式。 具體地說,高階元件就是一個接收一個元件並返回另外一個新元件的函式! 這是官方文件說的,我沒有截全,因為後面的解釋會造成誤解,但簡單講

邏輯迴歸80%都懂

1. 什麼是邏輯迴歸 邏輯迴歸是用來做分類演算法的,大家都熟悉線性迴歸,一般形式是Y=aX+b,y的取值範圍是[-∞, +∞],有這麼多取值,怎麼進行分類呢?不用擔心,偉大的數學家已經為我們找到了一個方法。 也就是把Y的結果帶入一個非線性變換的Sigmoid函式中,即可得到[0,1]之間取值範圍的數S,S可以

Linux基本的操作就

安裝 便在 變量名 format 速查 shell命令 一次 常用 根據 前言 只有光頭才能變強 本文章主要是總結Linux的基礎操作以及一些簡單的概念~如果不熟悉的同學可下個Linux來玩玩(或者去買一個服務器玩玩【學生版的不是很貴】),對於開發者來說,能使用Lin

wwwlyjustcom你就Linux基本操作請耐完199O8836661

command sts r文件 正常 內置命令 生態 regular ces 開頭 只有光頭才能變強這個學期開了Linux的課程了,授課的老師也是比較負責任的一位。總的來說也算是比較系統地學習了一下Linux了~本文章主要是總結Linux的基礎操作以及一些簡單的概念,對於開

你應該知道什麼是Linux~

Linux上的檔案系統一般來說就是EXT2或EXT3,但這篇文章並不準備一上來就直接講它們,而希望結合Linux作業系統並從檔案系統建立的基礎——硬碟開始,一步步認識Linux的檔案系統。 1.機械硬碟的物理儲存機制 現代計算機大部分檔案儲存功能都是由機械硬碟這種裝置

紅黑樹這個資料結構讓你又愛又恨?妥妥的征服它

紅黑樹是一個比較複雜的資料結構,相信很多人也只知其名而不知其意,因為理解它的原理確實需要花費一定的功夫。之所以寫這篇文章,也是為了更好的理解 Java 中 TreeMap 的原始碼。 寫之前,搜了下網上的文章,說實話,看完有點懵,大部分一上來就給你它的五大性質,然後就是一頓插入、刪除、旋轉操作,就完事了,理解

媽媽還擔心你Docker入不門?

“上週物件突然心血來潮說想養個小寵物,我問想養啥她又說隨便,你看著辦!!! 這我真的比較難辦啊!但是咱們程式設計師能有個物

我確定你已經徹底搞懂Java的繼承

遇到認真的讀者是作者的一種幸運,真的,上一篇介面推送後,有好幾個讀者留言說,“二哥,你有一處內容需要修正,應該是介面中不能有 private 和 protected 修飾的方法。”說實話,看到這樣的留言,我內心是非常欣慰的,因為你投出去的一塊石頭在水面上激起了一串美麗的漣漪。 在 Java 中,一個類可以繼承

再也不怕被問到 AsyncTask 的原理

本文很多資料基於[Google Developer](https://developer.android.google.cn/reference/android/os/AsyncTask?hl=en)官方對AsyncTask的最新介紹。 ### AsyncTask 是什麼 ``` AsyncTask

才能說解併發底層技術

>愛生活,愛編碼,本文已收錄[架構技術專欄](http://www.jiagoujishu.com/)關注這個喜歡分享的地方。本文 架構技術專欄 已收錄,有各種JVM、多執行緒、原始碼視訊、資料以及技術文章等你來拿 ## 零、開局 前兩天我搞了兩個每日一個知識點,對多執行緒併發的部分知識做了下概括性

再也不怕面試官問我執行緒池

![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201129220549759.png) ## 一、為什麼需要執行緒池 在實際使用中,執行緒是很佔用系統資源的,如果對執行緒管理不完善的話很容易導致系統問題。因此,在大多數併發框架中都會使用執行緒池來管理執行緒,使用執行緒

你就知道Python生成器是什麼

生成器是 Python 初級開發者最難理解的概念之一,雖被認為是 Python 程式設計中的高階技能,但在各種專案中可以隨處見到生成器的身影,你得不得去理解它、使用它、甚至愛上它。 提到生成器,總不可避免地要把迭代器拉出來對比著講,生成器就是一個在行為上和迭代器非常類似的物件,如果把迭代器比

你就知道 Lineage OS 系統的一切

前幾天看到新聞,發現 CM 團隊做出的新專案 Lineage OS 系統,一經官方釋出,就備受刷機黨們的關注。下面我來詳細講述一下我刷這個系統的整個過程以及體驗。   Lineage OS 系統介紹 大夥還記得 CyanogenMod 嗎?給安卓手機刷過機的使用者基本都知

【Android開發經驗】APP的快取檔案到底應該存在哪?文章你應該就自己清楚

只要是需要進行聯網獲取資料的APP,那麼不管是版本更新,還是圖片快取,都會在本地產生快取檔案。那麼,這些快取檔案到底放在什地方合適呢?系統有沒有給我們提供建議的快取位置呢?不同的快取位置有什麼不同呢?今天這篇文章就是主要來說明這個問題的。     首先,我們要知道,在A

別說你還不懂Hinton大神的膠囊網路capsule network

倒計時 2 天 來源 | 王的機器(公眾號ID:MeanMachine1031) 作者 | 王聖元 0 引言 斯蒂文認為機器學習有時候像嬰兒學習,特別是在物體識別上。比如嬰兒首先學會識別邊界和顏色,然後將這些資訊用於識別形狀和圖形等更復雜的實體。比如在人臉識別上

https證書申請難嗎?保證不難!

https證書的出現,解決了傳統http網站的使用者隱私資料傳輸不安全的問題。如今大部分重要網站都安裝上了https證書,享受著它

保證讓你真正明白:分散式系統的CAP理論、CAP如何三選二

引言 CAP 理論,相信很多人都聽過,它是指: 一個分散式系統最多隻能同時滿足一致性(Consistency)、可用性(Availability)和分割槽容錯性(Partition tolerance)這三項中的兩項。 為什麼要理解 CAP 理論?我能說出很多理由來。如果是在職場上,也許最合適的理由是,當領導

Java程式設計師想高薪文章就夠

Java作為一門程式語言,在各類程式語言中作為弄潮兒始終排在前三的位置,這充分肯定了java語言的魅力,在實際專案應用中,我們已經無法脫離java,它的高效能,穩定性,擴充套件性已經深入到每一個java程式設計工程師的骨髓裡。 然而要想成為一名合格的java工程師並不容易。因為作為一名Ja

一定進入人工智慧行業的理由文章你或許就懂

當今,全球科技界最炙手可熱的名詞莫過於“人工智慧”,全球科技巨頭諸如谷歌、微軟、蘋果、IBM、F

為什麼有紅黑樹?什麼是紅黑樹?畫20張圖你就明白

為什麼要有紅黑樹 想必大家對二叉樹搜尋樹都不陌生,首先看一下二叉搜尋樹的定義: 二叉搜尋樹(Binary Search Tree),或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的