高阶组件就是接受一个组件做为参数并返回一个新组件的函数。这里须要注意高阶组件是一个函数,并非组件,这一点必定要注意。同时这里强调一点高阶组件自己并非 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; }} /> ); } }