高阶组件
高阶组件是一个函数,接收一个组件,然后返回一个新的组件。 ——高阶组件
高阶组件的简介
1. 为什么需要高阶组件?
- 这个问题很简单,为什么我们需要react/vue/angular?
使用框架最核心的原因之一就是提高开发效率,能早点下班。同理,react高阶组件能够让我们写出更易于维护的react代码,能再早点下班~ - 举个栗子,ES6支持使用import/export的方式拆分代码功能和模块,避免一份文件里面出现"成坨"的代码。同理对于复杂的react组件,如果这个组件有几十个自定义的功能函数,自然要进行拆分,不然又成了"一坨"组件,那么该如何优雅地拆分组件呢?react高阶组件应运而生。
- 在使用ES5编写react代码时,可以使用Mixin这一传统模式进行拆分。新版本的react全面支持ES6并提倡使用ES6编写jsx,同时取消了Mixin。因此高阶组件越来越受到开源社区的重视,例如redux等知名第三方库都大量使用了高阶组件。
2. 高阶组件是什么?
- 回答这个问题前,看上图图,高阶函数就是形如y=kx+b的东西,x是我们想要改造的原组件,y就是改造过后输出的组件。那具体是怎么改造的呢?k和b就是改造的方法。这就是高阶组件的基本原理,是不是一点也不高阶~
- 再举个栗子相信更能让你明白:我们写代码需要进行加法计算,于是我们把加法计算的方法单独抽出来写成一个加法函数,这个加法函数可以在各处调用使用,从而减少了工作量和代码量。而我们独立出来的这个可以随处使用的加法函数,类比地放在react里,就是高阶组件。
3. 如何实现高阶组件?
- 从上面的问题回答中,我们知道了:高阶组件其实就是处理react组件的函数。那么我们如何实现一个高阶组件?有两种方法:
- 1.属性代理
- 2.反向继承
高阶组件(HOC)是React中用于复用组件逻辑的一种高级技巧。HOC自身不是React API的一部分,他是一种基于React的组合特性而形成的数据模式。
很多人看到高阶组件(HOC)这个概念就被吓到了,认为这东西很难,其实这东西概念真的很简单,我们先来看一个例子。
function add(a, b) {
return a + b
}
现在如果我想给这个 add 函数添加一个输出结果的功能,那么你可能会考虑我直接使用 console.log 不就实现了么。说的没错,但是如果我们想做的更加优雅并且容易复用和扩展,我们可以这样去做:
function add(a, b) {
return a + b
}
function withLog (fn) {
function wrapper(a, b) {
const result = fn(a, b)
console.log(result)
return result
}
return wrapper
}
const withLogAdd = withLog(add)
withLogAdd(1, 2)
其实这个做法在函数式编程里称之为高阶函数,大家都知道 React 的思想中是存在函数式编程的,高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好的复用代码。
具体而言,高阶组件是参数为组件,返回值为新组件的函数。
const EnhancedComponent = higherOrderComponent(WrappedComponent);
组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件。
接下来,我们将讨论为什么高阶组件有用,以及如何编写自己的 HOC 函数。
使用 HOC 解决横切关注点问题
注意:
我们之前建议使用 mixins 用于解决横切关注点相关的问题。但我们已经意识到 mixins 会产生更多麻烦。阅读更多 以了解我们为什么要抛弃 mixins 以及如何转换现有组件。
其实 HOC 和 Vue 中的 mixins 作用是一致的,并且在早期 React 也是使用 mixins 的方式。但是在使用 class 的方式创建组件以后,mixins 的方式就不能使用了,并且其实 mixins 也是存在一些问题的,比如:
- 隐含了一些依赖,比如我在组件中写了某个 state 并且在 mixin 中使用了,就这存在了一个依赖关系。万一下次别人要移除它,就得去 mixin 中查找依赖
- 多个 mixin