React的高階組件
高階組件基本介紹
什么是高階組件呢? 在認識高階組價之前, 我們先來回顧一下什么是高階函數(shù)?
相信很多同學都知道(聽說過?),也用過高階函數(shù)
高階組件和高階函數(shù)它們非常相似的
高階函數(shù)的定義, 至少滿足以下條件之一:
接受一個或多個函數(shù)作為參數(shù);
返回一個新的函數(shù);
JavaScript中比較常見的filter、map、reduce都是高階函數(shù)。
那么什么是高階組件呢?
高階組件的英文是 Higher-Order Components,簡稱為 HOC;
官方的定義: 高階組件是一個
參數(shù)為組件
,并且返回值為新組件
的函數(shù)
;
我們可以進行如下的解析:
首先, 高階組件本身不是一個組件,而是一個函數(shù);
其次,這個函數(shù)的參數(shù)是一個組件,返回值也是一個組件;
演示代碼如下, 我們可以在高階組件內(nèi)部定義一個類組件或者函數(shù)組件作為返回結果
定義類組件返回
// 定義一個高階組件
// 1.高階組件會接收一個組件作為參數(shù)
function hoc(Cpn) {
class NewCpn extends PureComponent {
}
// 2.并且返回一個新的組件
return NewCpn
}
定義函數(shù)組件返回
// 定義一個高階組件
// 1.高階組件會接收一個組件作為參數(shù)
function hoc(Cpn) {
function NewCpn() {
}
// 2.并且返回一個新的組件
return NewCpn
}
高階組件使用過程
高階組件的編寫和調(diào)用過程類似于下面這樣:
// 定義一個高階組件
// 1.高階組件會接收一個組件作為參數(shù)
function hoc(Cpn) {
class NewCpn extends PureComponent {
render() {
return <Cpn/>
}
}
// 2.并且返回一個新的組件
return NewCpn
}
// 創(chuàng)建一個組件作為參數(shù)
class HelloWorld extends PureComponent {
render() {
return <h2>Hello World</h2>
}
}
// 調(diào)用高階組件會返回一個新的組件
const HelloWorldHOC = hoc(HelloWorld)
export class App extends PureComponent {
render() {
return (
<div>
{/* 返回的新組件展示到App組件中 */}
<HelloWorldHOC/>
</div>
)
}
}
高階組件并不是React API的一部分,它是基于React的 組合特性而形成的設計模式;
高階組件在一些React第三方庫中非常常見:
比如redux中的connect;(后續(xù)文章會講到)
比如react-router中的withRouter;(后續(xù)文章會講到)
高階組件應用場景
應用一: props增強
例如我們可以定義一個高階組件, 對傳入的組件進行props增強, 也就是為傳入的組件添加一些參數(shù), 需要注意的是, 如果傳入的組件本身也有傳遞參數(shù)的話, 我們在為組件注入要增強的參數(shù)的同時, 還需要將本身傳遞的參數(shù)也注入進來, 實例代碼如下:
// 定義一個高階組件, 對傳入的組件進行props增強
function enhancedProps(WrapperCpn) {
class NewComponent extends PureComponent {
constructor() {
super()
this.state = {
userInfo: {
name: "chenyq",
age: 18
}
}
}
render() {
// 如果組件本身也有傳遞參數(shù), 也需要將參數(shù)添加進來
return <WrapperCpn {...this.props} {...this.state.userInfo}/>
}
}
return NewComponent
}
// 調(diào)用高階組件, 對組件進行props增強
const Home = enhancedProps(function(props) {
return <h2>{props.name}-{props.age}</h2>
})
const About = enhancedProps(function(props) {
return <h2>{props.name}-{props.age}-{props.names}</h2>
})
export class App extends PureComponent {
render() {
return (
<div>
{/* 展示增強后的組件 */}
<Home/>
{/* 本身也有傳遞參數(shù) */}
<About names={["aaa", "bbb", "ccc"]}/>
</div>
)
}
}
也可以利用高階組件來共享Context
function withTheme(OriginComponment) {
return (props) => {
return (
<ThemeContext.Consumer>
{
value => {
return <OriginComponment {...value} {...props}/>
}
}
</ThemeContext.Consumer>
)
}
}
應用二: 渲染判定鑒權
在開發(fā)中,我們可能遇到這樣的場景:
某些頁面是必須用戶登錄成功才能進行進入;
如果用戶沒有登錄成功,那么直接跳轉到登錄頁面;
這個時候,我們就可以使用高階組件來完成鑒權操作:
// 定義一個高階組件, 用于鑒權的操作
function loginAuth(WrapperCpn) {
return props => {
// 從本地存儲中獲取token, token有值表示已登錄, 沒有值表示未登錄
const token = localStorage.getItem("token")
if(token) {
return <WrapperCpn {...props}/>
} else {
return <h2>請先登錄, 再跳轉到對應的頁面中</h2>
}
}
}
const Cart = loginAuth(function() {
return <h2>購物車頁面</h2>
})
export class App extends PureComponent {
render() {
return (
<div>
<Cart/>
</div>
)
}
}
高階組件的意義
我們會發(fā)現(xiàn)利用高階組件可以針對某些React代碼進行更加優(yōu)雅的處理。
其實早期的React有提供組件之間的一種復用方式是mixin,目前已經(jīng)不再建議使用
:
Mixin 可能會相互依賴,相互耦合,不利于代碼維護;
不同的Mixin中的方法可能會相互沖突;
Mixin非常多時,組件處理起來會比較麻煩,甚至還要為其做相關處理,這樣會給代碼造成滾雪球式的復雜性;
當然,HOC也有自己的一些缺陷:
HOC需要在原組件上進行包裹或者嵌套,如果大量使用HOC,將會產(chǎn)生非常多的嵌套,這讓調(diào)試變得非常困難;
HOC可以劫持props,在不遵守約定的情況下也可能造成沖突;
Hooks的出現(xiàn),是開創(chuàng)性的,它解決了很多React之前的存在的問題
比如this指向問題、比如hoc的嵌套復雜度問題等等;文章來源:http://www.zghlxwxcb.cn/news/detail-789732.html
后續(xù)我還會專門來學習講解hooks相關的知識;文章來源地址http://www.zghlxwxcb.cn/news/detail-789732.html
到了這里,關于React的高階組件詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!