React 性能优化之高阶组件

188 阅读2分钟

高阶组件介绍

高阶组件简称 HOC,本身不是 React API 的一部分,而是基于 react 的组合特性而形成的一种设计模式。

React 的宗旨是专注于视图层,而对于组件内部的业务逻辑代码,React 想把它们托付出去,这样就会大大节省组件本身的性能。

而高阶组件就是 React 用于复用组件逻辑,将组件本身和业务逻辑代码分离的一种高级技巧。但是它有固定的套路和语法,这些都是硬性要求。

  • 高阶组件本身是一个函数

  • 接受组件为参数

  • 该函数返回一个新的类组件

案例对比

现在我们写两个组件,里面的内容都是计时器。

普通写法

//计时器组件
class Clock extends React.Component {
    constructor(props) {
      super(props);
      this.state = {date: new Date()};
    }

      componentDidMount() {
        this.timerID = setInterval(
        () => this.tick(),
        1000
      );
    }
    componentWillUnmount() {
      clearInterval(this.timerID);
    }
    tick() {
      this.setState({
        date: new Date()
      });
    }
    render() {
      return (
        <div>
          <h1>Hello, world!</h1>
          <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
        </div>
      );
    }
  }​

  class A extends React.Component {
      render() {
          return (
              <div>
                  <Clock/>
              </div>
          )
      }
  }
  class B extends React.Component {
    render() {
        return (
            <div>
                <Clock/>
            </div>
        )
    }
}
class App extends React.Component {
    render() {
        return (
            <div>
                <A></A>
                <B></B>
            </div>
        )
    }
}
export default App

通过上面代码,我们可以看到,首先定义一个 Clock 组件,然后跟 A 组件和 B 组件组合成父子组件,再将 A 和 B 组件添加到 App 组件内,这里面是对组件 Clock 组件的复用。

高阶组件写法

function A(props) {
    // console.log(props)
    return (<><h2>It is{props.dates.toLocaleTimeString()}</h2></>)
}
function B(props) {
    return (<><h2>It is{props.dates.toLocaleTimeString()}</h2></>)
}
function WithComponent(Oldcomponent) {
    class NewComponent extends Component {
        constructor(props) {
            super(props)
            this.state = {date: new Date()};
        }
        componentDidMount() {
            this.timerID = setInterval(
              () => this.tick(),
              1000
            );
        }
        componentWillUnmount() {
            clearInterval(this.timerID);
        }
        tick() {
            this.setState({
              date: new Date()
            });
        }
        render() {
            return (
              <div>
                <Oldcomponent dates = {this.state.date}></Oldcomponent>
              </div>
            );
          }​

    }
    return NewComponent;
}
const Aco = WithComponent(A)
const Bco = WithComponent(B)​

class App extends React.Component {
    render() {
        return (
            <div>
                <Aco></Aco>
                <Bco></Bco>
            </div>
        )
    }
}
export default App

高阶组件里的写法就不是对组件的复用了,而是对业务逻辑的复用。我们只要去调用这个高阶组件函数,就会得到一个我们需要的计时器组件。当state发生改变,在界面更改的过程只需要这个新组件更新,而不像前者需要每个组件都要更新,这样就大大优化了整个应用的性能体验。