学习高阶组件时要记住的关键思想是,它们旨在支持组件之间的代码重用而已,这就是为什么它们存在的原因。
现在,有些思想我们需要记住,
- 所谓高阶组件,就是传入一个组件返回另一个组件
- 高阶组件引用了高阶函数,然而,它们可以支持类组件和函数组件。
- 它们可能有点笨重而不受待见
- 在很多框架中使用的高阶组件,因此它们仍会流行一段时间
- HOC 就是高阶组件
实例:withRouter
让我们看一个真实的例子,
大多数稍微复杂的React项目,都会使用Router库,当你组件要绑定到路由时,比如
<code><route>/<code>
FooComponent 组件可以 在props中获得 history,location以及match对象等挂在路由上的对象。
但有时候不能用这样的方式让组件可以访问到路由上的对象,
所以我们需要用到 withRouter HOC:
<code>import { withRouter } from 'react-router-dom';
function NavBar (){
// ...DO STUFF...
// including access props.history, props.location and props.match
return (/*...*/)
}
export default withRouter(NavBar)/<code>
您可以看到不是返回NavBar 组件,而是返回HOC包装后的组件
这个是基本的思想,提取公用的功能,放在包装组件内,然后将这些功能赋予传入的组件并返回新的组件。
如果需要多个HOC,我们该怎么办?
我们可以包多个:withState(withRouter(navBar))。
创建HOC
当你的项目需要跨组件共享一些通用的功能时,便可以考虑使用HOC
你要做的是确定共享的功能,将其提取到包装组件上,包装组件与被包装组件进行通信,从而使HOC和客户端组件尽量解耦。
实际上,这是HOC通过prop与客户端组件交互的方式。道具是向组件提供所需信息的标准方法,并且通过它们进行交互,无论组件是否被HOC包装,组件都可以以完全相同的方式存在。
包装的所有组件需要知道的是,道具在运行时可用。
因此,我们可以将HOC视为框架和组件之间的抽象层,而这正是它们的本质。
您的HOC可以是一个简单的功能组件,其一般形式如下所示(这with*是常规的命名模式):
<code>const withSomething = WrappedComponent => {
const something = // do something generically useful with something
return props => <wrappedcomponent> {…props}/>;
};/<wrappedcomponent>/<code>
因此,基本思路是在HOC内执行一些有用的服务,然后将其结果WrappedComponent与其他道具一起通过传播算子传递到中。
最后一点很重要,因为它可以使使用代码所传递的其他所有道具都可用。这使它对包裹的组件透明。
随着钩子的出现,您的功能HOC可以完成类组件可以完成的所有工作,包括利用生命周期点并处理状态。
大型应用程序中出现的一种常见模式是将状态提取到HOC中,然后争取一个纯粹的表示性组件,以响应由HOC管理的状态。
也许您应该使用…
除了用于代码共享的HOC,您还应该注意其他选择。
Mixins (bad)
首先是较旧的选项:mixins。Mixins是一种众所周知的JavaScript技术。它们在React中不受欢迎,因为它们遇到了一些问题,例如名称空间冲突,以及它们在复杂场景中的功能变得晦涩难懂。
鉴于HOC,后来的批评很有趣:我想知道,HOC是否会遇到同样的问题?
Inheritance(皱眉)
继承是代码重用的标准OOP样式。对于组件的紧密耦合,这是一种不好的做法。它对于功能组件也不起作用。
在现代,即使是面向对象的专家也倾向于强调组成而不是继承。
Render props
另一种选择是渲染道具。有时渲染道具可以提供更清洁的体验。您必须先看一下要确定更好的选择的具体操作。
Hooks
另一种方法是定义自定义挂钩,如所描述这里。
閱讀更多 慕西 的文章