一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
前言
大家好呀,我是L同学。在上篇文章中react基础(十一),我们学习了react中的事件总线和ref的使用和类型。接下来,我们将学习到react中高阶组件的知识点。
什么是高阶组件
高阶组件(Higher-Order Component, HOC)是什么呢?在学习高阶组件之前,我们听说过高阶函数,它们非常相似,所以我们先来学习下什么是高阶函数。
高阶函数至少满足以下条件之一:
- 接收一个或多个函数作为输入;
- 输出一个函数
那么什么是高阶组件呢?官方定义为高阶组件是参数为组件,返回值为新组件的函数。
我们来解读下。第一,高阶组件是一个函数,本身不是一个组件。第二,这个函数的参数是一个组件,返回值也是一个组件。
高阶组件的使用
我们通过代码来看下高阶组件。enhanceComponent是一个高阶组件,接收的参数是一个组件,返回值是一个组件。
function enhanceComponent(WrappedComponent) {
class NewComponent extends PureComponent {
render() {
return <WrappedComponent/>
}
}
return NewComponent
}
我们先定义一个App组件,然后作为参数传入高阶组件。
class App extends PureComponent {
render() {
return (
<div>
App
</div>
)
}
}
调用高阶组件,并且传入App组件。
const EnhanceComponent = enhanceComponent(App)
然后通过export default进行导出。
export default EnhanceComponent
我们可以看到页面可以正常显示。并且在调试工具这儿可以看到类名
在ES中,类表达式的类名是可以省略的。所以我们也可以这样写。
function enhanceComponent(WrappedComponent) {
return class extends PureComponent {
render() {
return <WrappedComponent/>
}
}
}
我们可以看到此时调试工具这儿的类名变成了匿名。
为了方面调试,我们可以通过disPlayName来修改组件名称。组件的名称都可以通过displayName来修改。
function enhanceComponent(WrappedComponent) {
class NewComponent extends PureComponent {
render() {
return <WrappedComponent/>
}
}
NewComponent.displayName = 'haha'
return NewComponent
}
此时我们看到调试工具的组件名称变为了haha。
在开发中,我们会通过组件传递数据。现在我们往App组件中传递name,希望App组件能接受到name,并进行渲染。
ReactDOM.render(<App name='haha'/>, document.getElementById('root'))
在App组件中通过props进行接收。
class App extends PureComponent {
render() {
return (
<div>
App: {this.props.name}
</div>
)
}
}
但是此时,页面上没有渲染name数据,因为App组件接收到的是undefined,undefined在页面中不显示。
App组件不能渲染这是因为
<App name='haha'/> 这个组件本质上NewComponent,那么传递过来的name属性本质上是传给了NewComponent。因此我们可以通过之前讲过的...语法来获取到传递过来的name属性。
<WrappedComponent {...this.props}/>
此时我们可以看到页面正常渲染了name属性。
刚刚我们在高阶组件中返回的是类组件。除了类组件,高阶组件还可以返回函数组件。
function enhanceComponent2(WrappedComponent) {
function NewComponent(props) {
return <WrappedComponent {...props}/>
}
NewComponent.displayName = 'xixi'
return NewComponent
}
const EnhanceComponent = enhanceComponent2(App)
需要注意的是,高阶组件并不是react API的一部分,它是基于react的组合特性而形成的设计模式。高阶组件在一些react第三方库中非常常见。比如redux中的connect,react-router中的withRouter。我们后续进行讲解。