HigherOrderComponent
阅读之前,首先要问下自己:前端为什么要进行组件化开发
什么是高阶组件?
高阶组件就是一个函数
,该函数的特点是需要给它传递一个组件作为参数(参数还可以包含其他的数据),它会返回一个新的组件。
高阶组件定义示例:
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
高阶组件使用分析:
上面使用的两个组件InputWithUserName
和TextareaWithContent
在需求上有一个相同的逻辑:都是在挂载阶段从LocalStorage中加载特定字段数据。
如果不使用高阶组件,我们可能是针对每一个组件都加上componentWillMount
生命周期,然后在里面调用 LocalStorage 。后期假设需求改成使用 ajax 获取而不是从 LocalStorage 获取,不使用高阶组件的话我们需要针对每一个组件进行逻辑代码的修改,而使用高阶组件的话只需要修改高阶组件里面的逻辑,然后修改下引入的高阶组件(包装函数)的名称就行了。
使用高阶组件,就是把这些组件里面的相同逻辑抽离出来放入到一个包裹函数中。使用不同组件的时候都调用该高阶组件实现其已经封装好的功能,而不需要自己单独去实现。这样减少了开发单独组件所需的代码,充分复用了逻辑代码。
References