High Order Component(HOC) 高阶组件

根据reactJs官方文档的定义,HOC如下:
在这里插入图片描述
简要来讲的话,是一种重复利用组件逻辑的技术,接受一个组件,并且返回一个组件。
在这里插入图片描述
就上上面的例子一样,会接受WrappedComponent然后返回enhancedComponent.下面举例子来讲解。

1.创建一个按钮组件,并且监听点击次数

import React, { Component, useState, useEffect } from "react";

class ClickCounter extends Component {
  constructor() {
    super();
    this.state = {
      count: 0
    };
    this.incrementCount = this.incrementCount.bind(this);
  }

  incrementCount() {
    this.setState(preveState => {
      return {
        count: preveState.count + 1
      };
    });
  }

  render() {
    let { count } = this.state;
    return (
      <div>
        <button onClick={this.incrementCount}>Clicked {count} times</button>
      </div>
    );
  }
}

export default ClickCounter;

以上按钮组件我们创建了按钮组件并且监听了点击事件,然后增加了被点击的次数.

后来我们又接到了一个需求,是要做一个监听hover次数的组件。

创建一个监听Hover次数的组件

我们很快做出来了,其实我们做的过程中只是改了事件,其余的从ClickCounter这里复制粘贴了过来。

class HoverCounter extends Component {
  constructor() {
    super();
    this.state = {
      count: 0
    };
    this.incrementCount = this.incrementCount.bind(this);
  }

  incrementCount() {
    this.setState(preveState => {
      return {
        count: preveState.count + 1
      };
    });
  }

  render() {
    let { count } = this.state;
    return (
      <div>
        <h2 onMouseOver={this.incrementCount}>Hovered {count} times</h2>
      </div>
    );
  }
}

然后我们做完了以后,又来了一个需求,说要写一个监听input有多少次keypressed.这个时候我们想到的第一个办法,就复制粘贴上面写的两个组件的方法,改一改事件监听函数,但我们聪明起来了,我们想到写一个父组件,然后把count和incrementCount方法通过props的方式传下来到ClickCounter,HoverCounter组件.比如一下:
在这里插入图片描述
这样可以解决问题,在我们这个场景可以解决问题,但如果是一下情况就不太行了 。

在这里插入图片描述
把逻辑代码移到最上层的组件,不是一个好的解决方式。这个时候HOC闪亮登场了,它的作用就是在组件间分享重用的逻辑代码,接受一个组件,并且返回一个增强的组件。

我们定义一个WithCounter组件,作为HOC

import React, { Component, useState, useEffect } from "react";

const UpdatedComponent = OriginalComponent => {
  class NewComponent extends Component {
    render() {
      return <OriginalComponent name="Abdulla" />;
    }
  }

  return NewComponent;
};

export default UpdatedComponent;

可以看到我们实现了一个组件,这个组件接受名字叫originalComponent的组件,然后返回newComponent组件。
我们在这里为了演示在originalComponent那里传了一个props,为name=“Abdulla”。
下面来看ClickCounter,HoverCounter组件有了什么变化.
在这里插入图片描述
我们可以看到两处有了变化,import和export那里有了变化。然后可以看到我们通过this.props.name来使用了刚才传进来的props.
在HoverCounter组件也类似,可以看到起了作用.
在这里插入图片描述

把count和incrementCount逻辑放到HOC组件里。

1.)我们首先把在ClickCounter和HoverCounter里的count和incrementCount逻辑移出去。
2.)在WithCounter(HOC组件)里写count和incrementCount逻辑,然后通过props传出去,就像我们传name一样。
3.)然后在ClickCounter和HoverCounter组件里使用这个props.
最后展示一下这3个组件的代码
ClickCounter组件:

import React, { Component, useState, useEffect } from "react";
import UpdatedComponent from "./WithCounter";

class ClickCounter extends Component {
  constructor() {
    super();
    // this.state = {
    //   count: 0
    // };
    // this.incrementCount = this.incrementCount.bind(this);
  }

  //   incrementCount() {
  //     this.setState(preveState => {
  //       return {
  //         count: preveState.count + 1
  //       };
  //     });
  //   }

  render() {
    // let { count } = this.state;
    return (
      <div>
        <button onClick={this.props.incrementCount}>
          {this.props.name} Clicked {this.props.count} times
        </button>
      </div>
    );
  }
}

export default UpdatedComponent(ClickCounter);

没有删掉count和incrementCount逻辑,只是注释了,为了展示的更好,显示HOC组件的优越性。

HoverCounter组件如下:

import React, { Component, useState, useEffect } from "react";
import UpdatedComponent from "./WithCounter";

class HoverCounter extends Component {
  constructor() {
    super();
    // this.state = {
    //   count: 0
    // };
    // this.incrementCount = this.incrementCount.bind(this);
  }

  //   incrementCount() {
  //     this.setState(preveState => {
  //       return {
  //         count: preveState.count + 1
  //       };
  //     });
  //   }

  render() {
    // let { count } = this.state;
    return (
      <div>
        <h2 onMouseOver={this.props.incrementCount}>
          {this.props.name} Hovered {this.props.count} times
        </h2>
      </div>
    );
  }
}

export default UpdatedComponent(HoverCounter);

WithCounter组件如下:

import React, { Component, useState, useEffect } from "react";

const UpdatedComponent = OriginalComponent => {
  class NewComponent extends Component {
    constructor() {
      super();
      this.state = {
        count: 0
      };
      this.incrementCount = this.incrementCount.bind(this);
    }

    incrementCount() {
      this.setState(preveState => {
        return {
          count: preveState.count + 1
        };
      });
    }

    render() {
      return (
        <OriginalComponent
          name="Abdulla"
          count={this.state.count}
          incrementCount={this.incrementCount}
        />
      );
    }
  }

  return NewComponent;
};

export default UpdatedComponent;

总结起来,HOC的作用是为了精简代码,实现代码的复用.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章