高階組件就是接受一個組件做爲參數並返回一個新組件的函數。這裏須要注意高階組件是一個函數,並非組件,這一點必定要注意。同時這裏強調一點高階組件自己並非 React API。它只是一種模式,這種模式是由React自身的組合性質必然產生的。更加通俗的講,高階組件經過包裹(wrapped)被傳入的React組件,通過一系列處理,最終返回一個相對加強(enhanced)的 React 組件,供其餘組件調用。javascript
獲取方式:java
@withRouter export default class childComponent extends Component { constructor(props) { super(props); this.state = {}; const { getInstance } = props; if (typeof getInstance === 'function') { getInstance(this); // 在這裏把this暴露給`parentComponent` } } render() { return (<div>this is childComponent</div>) } } @withRouter export default class parentComponent extends Component { constructor(props) { super(props); this.state = {}; } render () { return ( <childComponent ref={(withRouter) => { this.childCpWrapper = withRouter; }} // 這裏獲取的是`withRouter`組件,通常沒啥用,這裏寫出來只是爲了對比 getInstance={(childCp) => { this.childCp = childCp; }} // 這裏經過`getInstance`傳一個回調函數接收`childComponent`實例便可 /> ); } }
下面將上面的方法優化一下,單獨寫一個類來獲取react
// 只作一件事,把`WrappedComponent`回傳個`getInstance`(若是有的話) export default (WrappedComponent) => { return class withRef extends Component { static displayName = `withRef(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`; render() { // 這裏從新定義一個props的緣由是: // 你直接去修改this.props.ref在react開發模式下會報錯,不容許你去修改 const props = { ...this.props, }; const { getInstance } = props; if (typeof getInstance === 'function') { // 在這裏把getInstance賦值給ref, // 傳給`WrappedComponent`,這樣就getInstance能獲取到`WrappedComponent`實例 props.ref = getInstance; } return ( <WrappedComponent {...props} /> ); } }; }; // 如何使用? @withRouter @withRef // 這樣使用是否是方便多了,注意:這句必須寫在最接近`childComponent`的地方 export default class childComponent extends Component { constructor(props) { super(props); this.state = {}; } render() { return (<div>this is childComponent</div>) } } @withRouter export default class parentComponent extends Component { constructor(props) { super(props); this.state = {}; } render () { return ( <childComponent // 這裏獲取的是`withRouter`組件,通常沒啥用,這裏寫出來只是爲了對比 ref={(withRouter) => { this.childCpWrapper = withRouter; }} // 這裏經過`getInstance`傳一個回調函數接收`childComponent`實例便可 getInstance={(childCp) => { this.childCp = childCp; }} /> ); } }