高阶组件:
以接收React组件为参数,并且返回一个新的React组件。
function widthPer(WrapComponent) { return class extends Component { componentWillMount() { this.data = 'i am commom data' } render() { return ( <WrapComponent data={this.data} {...this.props} /> ) } } }
class AboutState extends Component { render() { console.log(this.props.data) return ( <div> Hight </div> ) } }
一、使用场景:
1.1 操纵props
通过拦截到props,对props进行包装。
1.2 通过ref访问组件实例
通过ref获取包装组件实例的引用。
render() { return ( <WrapComponent ref={ref=>this.instance =ref}/> ) }
1.3组件状态提升
把组件状态提升到高阶组件
1.4用其他元素包装组件
render() { return ( <div> <WrapComponent ref={ref=>this.instance =ref}/> </div> ) }
二、参数传递
const widthPer = (key) => (WrapComponent) => { return class extends Component { componentWillMount() { this.data = key } render() { return ( <div> <WrapComponent ref={ref => this.instance = ref} data={this.data} /> </div> ) } } }
widthPer('i am param')(AboutState)
三、继承方式实现
function widthPer(WrapComponent) { return class extends WrapComponent { render() { if (this.state.logo) { return super.render() } else { return null } } } }
class AboutState extends Component { state = { logo: true } render() { return ( <div> Hight </div> ) } }
四、注意事项
4.1对高阶组件的显示名称自定义做处理
function widthPer(WrapComponent) { return class extends WrapComponent { static displayName=`HOC(${getDisplayName(WrapComponent)})` render() { if (this.props.logo) { return super.render() } else { return null } } } } function getDisplayName(wrapComonent){ return wrapComonent.displayName||wrapComonent.name||'Component' }
4.2定义位置
不要在组件的render中使用高阶组件,也不要在组件的其他生命周期中使用高阶组件。【每次调用高阶组件都会返回一个新的数组,于是每次render,前一次高阶组件创建的组件都会被卸载】,所以最合适的地方是在组件定义的外部。
4.3refs不会传递给包装组件