程序员

HigherOrderComponent

2018-07-03  本文已影响3人  oNexiaoyao

阅读之前,首先要问下自己:前端为什么要进行组件化开发

什么是高阶组件?

高阶组件就是一个函数,该函数的特点是需要给它传递一个组件作为参数(参数还可以包含其他的数据),它会返回一个新的组件。

高阶组件定义示例:

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
}

为什么要使用高阶组件?

高阶组件的作用:为了组件间的代码复用。

组件可能有着某些相同的逻辑,把这些逻辑抽离出来,放到高阶组件中进行复用。高阶组件内部的包装组件和被包装组件之间通过props传递数据。

如何使用高阶组件?

高阶组件使用示例:

InputWithUserName的功能需求是挂载的时候从localStorage里面加载username字段作为<input />的value值。

import wrapWithLoadData from './wrapWithLoadData'

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

//  具体的做法:先定义一个非常简单的InputWithUserName,然后把这个组件和username
//  传给wrapWithLoadData,wrapWithLoadData会返回一个新的组件,然后我们用这个新的组件
//  覆盖原来的InputWithUserName,然后再导出去模块
InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')
export default InputWithUserName

最终调用的该组件实际是用了被加工过的组件:

import InputWithUserName from './InputWithUserName'

class Index extends Component {
  render () {
    return (
      <div>
        用户名:<InputWithUserName />
      </div>
    )
  }
}

新的需求:另外一个文本输入框组件,它需要从LocalStorage加载content字段的数据。

import wrapWithLoadData from './wrapWithLoadData'

class TextareaWithContent extends Component {
  render () {
    return <textarea value={this.props.data} />
  }
}
// 应用之前定义好的高阶组件,只需要传递一个不同的参数
TextareaWithContent = wrapWithLoadData(TextareaWithContent, 'content')
export default TextareaWithContent

高阶组件使用分析:

上面使用的两个组件InputWithUserNameTextareaWithContent在需求上有一个相同的逻辑:都是在挂载阶段从LocalStorage中加载特定字段数据。

如果不使用高阶组件,我们可能是针对每一个组件都加上componentWillMount生命周期,然后在里面调用 LocalStorage 。后期假设需求改成使用 ajax 获取而不是从 LocalStorage 获取,不使用高阶组件的话我们需要针对每一个组件进行逻辑代码的修改,而使用高阶组件的话只需要修改高阶组件里面的逻辑,然后修改下引入的高阶组件(包装函数)的名称就行了。

使用高阶组件,就是把这些组件里面的相同逻辑抽离出来放入到一个包裹函数中。使用不同组件的时候都调用该高阶组件实现其已经封装好的功能,而不需要自己单独去实现。这样减少了开发单独组件所需的代码,充分复用了逻辑代码。

References

上一篇 下一篇

猜你喜欢

热点阅读