您好,登錄后才能下訂單哦!
這篇文章主要介紹了React高階組件怎么使用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇React高階組件怎么使用文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
高階組件也就是我們常說(shuō)的HOC,是React中用于復(fù)用組件邏輯的一種高級(jí)技巧。HOC自身不是React API的一部分,他是一種基于React的組合特性而形成的設(shè)計(jì)模式。
其實(shí)就是組件作為參數(shù),返回值也是組件的函數(shù),他是純函數(shù),不會(huì)修改傳入的組件,也不會(huì)使用繼承來(lái)復(fù)制其行為。相反,HOC通過(guò)將組件包裝在容器組件中來(lái)組成新組件。HOC是純函數(shù),沒(méi)有副作用。
抽取重復(fù)代碼,實(shí)現(xiàn)組件復(fù)用:相同功能組件復(fù)用
條件渲染,控制組件的渲染邏輯(渲染劫持):權(quán)限控制
捕獲/劫持被處理組件的生命周期,常見(jiàn)場(chǎng)景:組件渲染性能追蹤、日志打點(diǎn)。
先來(lái)看一個(gè)簡(jiǎn)單的HOC實(shí)現(xiàn)方式
function withLog(Component) { return function (props) { console.log(`[${new Date().toISOString()}] ${Component.name} props:`, props); return <Component {...props} />; }; }
這個(gè)HOC接收一個(gè)組件作為參數(shù),返回一個(gè)新的組件,新的組件在渲染之前會(huì)先輸出當(dāng)前時(shí)間和傳入的組件的名稱和props到控制臺(tái),然后再將props傳遞給原始組件進(jìn)行渲染。
使用這個(gè)HOC可以像下面這樣
function MyComponent(props) { return <div>{props.message}</div>; } const MyComponentWithLog = withLog(MyComponent); ReactDOM.render( <MyComponentWithLog message="Hello, world!" />, document.getElementById('root') );
渲染的時(shí)候控制臺(tái)會(huì)輸出
[2023-04-16T00:00:00.000Z] MyComponent props: { message: "Hello, world!" }
可以看到,HOC 可以用來(lái)增強(qiáng)組件的功能,比如添加日志、添加權(quán)限校驗(yàn)、添加數(shù)據(jù)預(yù)處理等。
其實(shí)HOC的實(shí)現(xiàn)方式主要分為兩種:屬性代理和反向繼承
使用組合的方式,將組件包裝在容器上,依賴父子組件的生命周期關(guān)系來(lái):
返回?zé)o狀態(tài)的函數(shù)組件
返回class組件
操作props
// 可以通過(guò)屬性代理,攔截父組件傳遞過(guò)來(lái)的porps并進(jìn)行處理。 // 返回一個(gè)無(wú)狀態(tài)的函數(shù)組件 function HOC(WrappedComponent) { const newProps = { type: 'HOC' }; return props => <WrappedComponent {...props} {...newProps}/>; } // 返回一個(gè)有狀態(tài)的 class 組件 function HOC(WrappedComponent) { return class extends React.Component { render() { const newProps = { type: 'HOC' }; return <WrappedComponent {...this.props} {...newProps}/>; } }; }
抽象state
通過(guò)屬性代理無(wú)法直接操作原組件的state,可以通過(guò)props和回調(diào)函數(shù)抽象state
function HOC(WrappedComponent) { return class extends React.Component { constructor(props) { super(props); this.state = { name: '', }; this.onChange = this.onChange.bind(this); } onChange = (event) => { this.setState({ name: event.target.value, }) } render() { const newProps = { name: { value: this.state.name, onChange: this.onChange, }, }; return <WrappedComponent {...this.props} {...newProps} />; } }; } // 使用 @HOC class Example extends Component { render() { return <input name="name" {...this.props.name} />; } }
這里我們稍微做一下解釋。我們主要的目的是想通過(guò)傳給HOC的這個(gè)組件來(lái)修改HOC的state,在HOC中定義了onChange方法目的是可以修改state。如果在WrappedComponent中調(diào)用onChange方法呢?我們可以定義一個(gè)對(duì)象作為WrappedComponent的props,然后將onChange方法存儲(chǔ)在定義的對(duì)象上,傳給WrappedComponent。
在WrappedComponent中,我們定義了一個(gè)input,我們都知道input有value屬性作為input的值,還有一個(gè)onChange方法作為change事件,我們把傳給WrappedComponent的props結(jié)構(gòu)剛好就是value和onChange。這樣當(dāng)input在change的時(shí)候就可以就修改state的值了。
通過(guò)props實(shí)現(xiàn)條件渲染
通過(guò)props來(lái)控制是否渲染及傳入數(shù)據(jù)
import * as React from 'react'; function HOC (WrappedComponent) { return (props) => ( <div> { props.isShow ? ( <WrappedComponent {...props} /> ) : <div>暫無(wú)數(shù)據(jù)</div> } </div> ); } export default HOC;
其他元素wrapper傳入的組件
function withBackgroundColor(WrappedComponent) { return class extends React.Component { render() { return ( <div style={{ backgroundColor: '#ccc' }}> <WrappedComponent {...this.props} {...newProps} /> </div> ); } }; }
使用一個(gè)函數(shù)接收一個(gè)組件作為參數(shù)傳入,并返回一個(gè)繼承了該傳入組件的類組件,且在返回組件的render()
方法中返回了super.render()
方法。
const HOC = (WrappedComponent) => { return class extends WrappedComponent { render() { return super.render() } } }
允許HOC通過(guò)this訪問(wèn)到原組件,可以直接讀取和操作原組件的state/ref等
可以通過(guò)render.super()
獲取傳入組件的render,可以有選擇的渲染劫持
劫持原組件生命周期方法
function HOC(WrappedComponent){ const didMount = WrappedComponent.prototype.componentDidMount; // 繼承了傳入組件 return class HOC extends WrappedComponent { async componentDidMount(){ // 劫持 WrappedComponent 組件的生命周期 if (didMount) { await didMount.apply(this); } ... } render(){ //使用 super 調(diào)用傳入組件的 render 方法 return super.render(); } } }
讀取/操作原組件的state
function HOC(WrappedComponent){ const didMount = WrappedComponent.prototype.componentDidMount; // 繼承了傳入組件 return class HOC extends WrappedComponent { async componentDidMount(){ if (didMount) { await didMount.apply(this); } // 將 state 中的 number 值修改成 2 this.setState({ number: 2 }); } render(){ //使用 super 調(diào)用傳入組件的 render 方法 return super.render(); } } }
通過(guò)this.setState({ number: 2 });
修改了原組件WrappedComponent
中的state的number值
條件渲染
const HOC = (WrappedComponent) => class extends WrappedComponent { render() { if (this.props.isRender) { return super.render(); } else { return <div>暫無(wú)數(shù)據(jù)</div>; } } }
修改react樹(shù)
// 修改返回render結(jié)果 function HigherOrderComponent(WrappedComponent) { return class extends WrappedComponent { render() { const tree = super.render(); const newProps = {}; if (tree && tree.type === 'input') { newProps.value = 'something here'; } const props = { ...tree.props, ...newProps, }; const newTree = React.cloneElement(tree, props, tree.props.children); return newTree; } }; }
這里首先通過(guò)super.render()
拿到需要渲染的樹(shù),然后對(duì)這個(gè)渲染樹(shù)做了修改。比如如果是一個(gè)input,則修改它的value值。
屬性代理:從"組合"角度出發(fā),有利于從外部操作WrappedComponent,可以操作props,或者在WrappedComponent外加一些攔截器(如:條件渲染,增加外部樣式)
反向繼承:從"繼承"角度出發(fā),從內(nèi)部操作WrappedComponent,可以操作組件內(nèi)部的state,生命周期和render等,功能更強(qiáng)大
關(guān)于“React高階組件怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“React高階組件怎么使用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。