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
) 等等。