想一想之前用原生和jQuery的項目,上千行的code映入眼簾,瞬間有種昏死過去的衝動。代碼難以維護,改一個bug可能出現N個bug,真的是很痛苦。因而乎組件化成爲了當前前端開發的主流技術。angular、vue和react很好的幫咱們實現了組件化。前端
可是咱們經常也會遇到一種狀況,就是兩個組件每每有不少的重複代碼(多是相同的屬性,也多是相同的方法)。例如,在登陸和註冊組件中,都會有用戶名和密碼,以及對他們的校驗規則。爲了提升代碼的複用性和可維護性,React高階函數應運而生。vue
React以前對此的解決方案是mixin,但這形成和不少沒必要要的問題,後來就被廢棄掉了。使用過vue的同窗,不知道有沒有使用過mixin,react高階函數的做用和它是同樣的。react
高階組件實際上是一個函數,它並非一個組件,咱們須要向它傳遞一些參數(想要操做的組件、屬性)。這麼提及來它其實一點也不高階,它的做用就是存儲一些公共的屬性和方法。chrome
咱們常常幾我的吃過一個鍋底的那種火鍋,鍋底裏有火鍋底料和各類佐料,咱們把肉和蔬菜等放進去涮一下,就能夠美美的飽餐一頓。高階函數在react編程中扮演的角色就是火鍋鍋底的角色,它有公用的方法和屬性,而各類組件就是肉和蔬菜。若是是一我的一個鍋的火鍋就像沒有通過封裝的code,代碼量重複且維護困難。編程
咱們先來看一段可使用高階函數的代碼:react-router
這裏有一個Second組件,它負責展現用戶名username函數
export class Second extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } render() { return( <div> <legend>Second Page</legend> <h2>Hi {this.state.username}</h2> </div> ) } }
下面是一個Third組件,它也負責展現用戶名組件化
export class Third extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } render() { return( <div> <legend>Third Page</legend> <h2>Hi {this.state.username}</h2> <p>我今年18歲了</p> </div> ) } }
咱們看到這兩個組件除了名稱之外,其他大量的代碼是同樣的,咱們徹底能夠考慮將它們通用的代碼提取出來。下面就是高階組件出場的時候了。this
高階組件能夠寫成這樣spa
export const HighOrderComponent = (WrapComponent, title) => { return class HOC extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } static displayName = `HOC(${getDisplayName(WrapComponent)})`; render() { return( <div> <legend>{title}</legend> <WrapComponent username={this.state.username}></WrapComponent> </div> ) } } }
使用高階組件以後咱們要對Second和Third組件進行修改,修改以下
class Second extends React.Component { render() { return( <div> <h2>Hi {this.props.username}</h2> <h3>曉不曉得哪裏好耍</h3> </div> ) } } export const HighOrderSecond = HighOrderComponent(Second, 'Second Page');
class Third extends React.Component { render() { return( <div> <h2>Hi {this.props.username}</h2> </div> ) } } export const HighOrderThird = HighOrderComponent(Third, 'Third Page');
不少同窗可能會問,export出去的常量是幹什麼用的,它就是高階組件對組件進行封裝以後的一個全新的組件,是二者的結合。到此,咱們在其它頁面引用組件就再也不是引用Second和Third組件了,要引用的就是HighOrderSecond和HighOrderThird了。
細心的同窗可能會發現一些不一樣的地方,對於Second和Third的公共legend提取出去了,但並無將h2對應得標題提取出去,這裏只是想給你們說一下,在對組件使用高階組件包裹以後,高階組件就變成了組件的父組件,它的state能夠經過props的方式向子組件傳遞,username就是這樣。咱們在chrome的react插件中能夠觀察到這一點
HOC已經將Second組件包裹起來,成爲了它的父組件,它上面的match和location是我使用了react-router的緣故,咱們能夠不用去管它。它的state——username做爲props傳給了Second
今天給你們簡單的介紹了React高階組件的一些知識,後續還會再深刻的挖掘React高階組件的知識和你們分享,但願對你們有幫助。文章轉自我的掘金帳號,轉載請註明出處,謝謝