函数式编程

高阶组件简介

2020-11-02  本文已影响0人  菜菜的小阿允
一、定义

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数,如:

const NewComponent = higherOrderComponent(OldComponent);
二、例子

高阶组件是一个函数(而不是组件),它接受一个组件作为参数,返回一个新的组件。这个新的组件会使用你传给它的组件作为子组件,我们可以看个例子来进一步理解一下。

import React, { Component } from 'react';
export default (WrappedComponent, name) => {
  class NewComponent extends Component {
    constructor () {
      super()
      this.state = { data: null }
    }

    componentWillMount () {
      let data = localStorage.getItem(name)
      this.setState({ data })
    }

    render () {
      return <WrappedComponent data={this.state.data} />
    }
  }
  return NewComponent;
}
import wrapWithLoadData from './wrapWithLoadData';

class InputWithUserName extends Component {
  render () {
    return <input value={this.props.data} />
  }
}

InputWithUserName = wrapWithLoadData(InputWithUserName, 'username');
export default InputWithUserName;
import InputWithUserName from './InputWithUserName';

class Index extends Component {
  render () {
    return (
      <div>
        用户名:<InputWithUserName />
      </div>
    )
  }
}
import wrapWithLoadData from './wrapWithLoadData';
class TextareaWithContent extends Component {
  render () {
    return <textarea value={this.props.data} />
  }
}
TextareaWithContent = wrapWithLoadData(TextareaWithContent, 'content');
export default TextareaWithContent;
三、高阶组件的灵活性

代码复用的方法、形式有很多种,可以用类继承来做到代码复用,也可以用分离模块的方式。但是高阶组件这种方式很有意思,也很灵活,它其实就是设计模式里面的装饰者模式,通过组合的方式达到很高的灵活程度。
假如现在需求变成了:需要先从 localStorage 中加载数据,再用这个数据去服务器取数据。

import React, { Component } from 'react';
import ajax from 'Ajax';

export default (WrappedComponent, name) => {
  class NewComponent extends Component {
    constructor () {
      super()
      this.state = { data: null }
    }

    componentWillMount () {
      ajax.get('/data/' + this.props.data, (data) => {
        this.setState({ data })
      })
    }

    render () {
      return <WrappedComponent data={this.state.data} />
    }
  }
  return NewComponent;
}
import wrapWithLoadData from './wrapWithLoadData'
import wrapWithAjaxData from './wrapWithAjaxData'

class InputWithUserName extends Component {
  render () {
    return <input value={this.props.data} />
  }
}

InputWithUserName = wrapWithAjaxData(InputWithUserName);
InputWithUserName = wrapWithLoadData(InputWithUserName, 'username');
export default InputWithUserName;
四、总结
上一篇 下一篇

猜你喜欢

热点阅读