上文提到react高阶组件的基本概念以及基本使用方式,下面将介绍高阶组件的应用方式。

代理方式的高阶组件

返回的新组件直接继承于React.Component类,新组件作为传入组件的一个代理,在新组件中渲染出被包裹组件。除了高阶组件自己要做的事情以外,其余全部由被包裹组件来做。
其有四种操作:

1、操纵props。
2、访问ref。
3、抽取状态。
4、包装组件。

1.操纵props:
我们拿组件B来做演示,给B加一个属性name。

import React from 'react';import B from './components/B'import C from './components/C'import './App.css';class App extends React.Component {  render() {    return (      <div>        <B name='李雷' />        <C />      </div>    );  }}

在B组件中把name通过props显示出来,但是发现上面并未对sex属性赋值,我们可以在高阶组件中进行传入。

import React, { Component } from 'react'import A from './A'@Aclass B extends Component {  render() {    console.log(this.props)    return (      <div>        <div>这是组件B</div>        <div>我的名字:{ this.props.name }</div>        <div>我的性别:{ this.props.sex }</div>      </div>    )  }}export default B

首先把根节点的props透传入组件B中,在添加一个新的属性sex。

import React, { Component } from 'react'export default function A(WrappedComponent) {  return class A extends Component {    render() {      return (        <div className="box">          <div>我是公共组件A的内容</div>          <WrappedComponent {...this.props} sex={'男'} />        </div>      )    }  }}

最终达到我们操作props的要求:

2.访问ref:
通过ref访问调用C的实例

import React, { Component } from 'react'export default function A(WrappedComponent) {  return class A extends Component {    refContent(instance) {      instance.putOutComponent && console.log(instance.putOutComponent())    }    render() {      return (        <div className="box">          <div>我是公共组件A的内容</div>          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } />        </div>      )    }  }}

在C中加入putOutComponent方法

import React, { Component } from 'react'import A from './A'class C extends Component {  putOutComponent() {    return '这是组件C'  }  render() {    console.log(this.props)    return (      <div>这是组件C</div>    )  }}export default A(C)

控制台中显示组件C中内容方法,这样可以控制所有被包裹组件,以便与业务扩展。

3.抽取状态:
把input的value值和onInputChange方法从高阶组件中以props方式传入。

import React, { Component } from 'react'import A from './A'@Aclass B extends Component {  render() {    return (      <div>        <input type='text' {...this.props} />        <br />        <div>这是组件B</div>        <div>我的名字:{ this.props.name }</div>        <div>我的性别:{ this.props.sex }</div>      </div>    )  }}export default B

设置newProps把value值和onInputChange传入,当输入内容改变时便会触发高阶组件onInputChange方法从而获取改变值的内容,同样可以在C组件中加入input在A高阶组件中进行控制。

import React, { Component } from 'react'export default function A(WrappedComponent) {  return class A extends Component {    constructor(props) {      super(props)      this.state = {        value: ''      }    }    refContent(instance) {      instance.putOutComponent && console.log(instance.putOutComponent())    }    onInputChange = (e) => {      console.log(e.target.value)      this.setState({        value: e.target.value      })    }    render() {      const newProps = {        value: this.state.value,        onInput: this.onInputChange      }      return (        <div className="box">          <div>我是公共组件A的内容</div>          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />        </div>      )    }  }}

4.包装组件:
包装组件指我们可以在高阶组件中设置公共部分,<div>我是公共组件A的内容</div>这里就是对组件的包装。

return (        <div className="box">          <div>我是公共组件A的内容</div>          <WrappedComponent { ...this.props } sex={ '男' } ref={ this.refContent } {...newProps} />        </div>      )

以上就是代理方式的高阶组件介绍。