HOC 谁好谁坏,就像技术本身就没有好坏之分,只有适合不适合。难道 React 和 Vue 这俩哥们儿不也是这样吗🙂。
ok ,我们回到高阶组件,所谓高阶组件其实就是高阶函数啦, React 和 Vue 都证明了一件事儿: 一个函数就是一个组件 。所以组件是函数这个命题成立了,那高阶组件很自然的就是高阶函数,即一个返回函数的函数,我们知道在 React 中写高阶组件就是在写高阶函数,很简单,那是不是在 Vue 中实现高阶组件也同样简单呢?其实 Vue 稍微复杂,甚至需要你对 Vue 足够了解,接下来就让我们一块在 Vue 中实现高阶组件,在文章的后面会分析为什么同样都是 函数就是组件 的思想, Vue 却不能像 React 那样轻松的实现高阶组件。
也正因如此所以我们有必要在实现 Vue 高阶组件之前充分了解 React 中的高阶组件,看下面的 React 代码:
function WithConsole (WrappedComponent) {
return class extends React.Component {
componentDidMount () {
console.log('with console: componentDidMount')
}
render () {
return <WrappedComponent {...this.props}/>
}
}
}
WithConsole 就是一个高阶组件,它有以下几个特点:
1、高阶组件( HOC )应该是无副作用的纯函数,且不应该修改原组件
可以看到 WithConsole 就是一个纯函数,它接收一个组件作为参数并返回了一个新的组件,在新组件的 render 函数中仅仅渲染了被包装的组件( WrappedComponent ),并没有侵入式的修改它。
2、高阶组件( HOC )不关心你传递的数据( props )是什么,并且被包装组件( WrappedComponent )不关心数据来源
这是保证高阶组件与被包装组件能够完美配合的根本
3、高阶组件( HOC )接收到的 props 应该透传给被包装组件( WrappedComponent )
高阶组件完全可以添加、删除、修改 props ,但是除此之外,要将其余 props 透传,否则在层级较深的嵌套关系中( 这是高阶组件的常见问题 )将造成 props 阻塞。
以上是 React 中高阶组件的基本约定,除此之外还要注意其他问题,如:高阶组件( HOC )不应该在 render 函数中创建;高阶组件( HOC )也需要复制组件中的静态方法;高阶组件( HOC )中的 ref 引用的是最外层的容器组件而不是被包装组件( WrappedComponent ) 等等。
