【Hooks系列2】Hooks之前,高阶组件和renderprops是如何实现逻辑复用的?
【Hooks系列2】Hooks之前,高阶组件和renderprops是如何实现逻辑复用的?
关注程序员耳东,编程转码真轻松
提供前端面试辅导服务、零基础前端自学辅导服务;免费修改前端简历,免费回答小问题
本篇笔记是Hooks系列的第二篇,欢迎关注我的【Hooks系列】,带你更好的学习和掌握Hooks
上一篇聊到了Hooks可以更好的解决逻辑复用的问题,那么在Hooks之前,React是如何实现逻辑复用的呢?
答案是在使用高阶组件和renderprops,这篇笔记就浅聊一下高阶组件和renderprops
本来是不想写这篇笔记的,因为这个系列的主题是Hooks,但是考虑到我们接手的很多项目技术不一定是比较新的,比如说我负责的几个项目技术都比较陈旧,把它们升级到新技术也废了很大的劲儿,所以我觉得写这篇笔记还是有意义的
高阶组件(hoc)
什么是高阶组件,先看一下原汁原味的英文文档是怎么说的:
A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature. Concretely, a higher-order component is a function that takes a component and returns a new component.
翻译成中文大白话就是,高阶组件就是一个函数,这个函数它接受一个组件,然后返回一个新的组件。它并不是React API的一部分,它是由React代码组合而来的一种模式,目的是复用组件逻辑
写个代码来解释一下,假如我们有两个组件,它们的代码是下面这样:
你可以发现它们俩的逻辑是类似的,都是以下这么几步:
- 在组件didMount的时候,给DataSource加上changeListener
- 在handleChange方法内部,把DataSource最新的值设置给组件内部的state
- 在组件willUnmount的时候,移除DataSource的changeListener
这些散在生命周期和方法中的逻辑应该如何复用呢?答案就是高阶组件,代码如下:
这个withSubscription组件就是一个高阶组件,它可以接收一个组件和一个参数使用规则的function,经过它内部的一顿包装,就可以让传入的组件复用withSubscription内部的逻辑,说白了它就像一台运行的机器一样,对每一个进入的组件都包装一层,然后再输出一个新的组件
但需要注意的是,我们在自己写高阶组件的时候,不要去改变传入的那个原始组件,我们只要组合并且给它传参就行
我们使用高阶组件的常见场景就是比如说数据获取、上下文获取、主题设置、权限控制等等,既可以包装类组件又可以包装函数组件
但是它的缺点也很明显,它会增加组件树的层级,并且如果是函数式组件内部逻辑复用的话,高阶组件就无能为力了
renderprops
什么是renderprops?看下英文文档怎么说:
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function. A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic
翻译成大白话就是,renderprops就是组件的某个参数是一个function,并且这个function返回一个React组件,以此来达到复用逻辑的目的
它跟高阶组件一样,也是一种写代码的模式,也就是所谓的套路,并不是React自带的API
比如说要写一个获取鼠标当前坐标的组件,那么可以这样写:
如果说此时我的项目中有多个需要使用到,但是又会有一些细微的变化,导致这个Mouse组件不能被复用,比如说如果我想做一个效果是有一个飞机图标跟随鼠标位置,那么肯定要根据鼠标当前最新的位置来画飞机图标,代码大概是下面这样,你肯定要给飞机组件传个位置过去
我们基于这个思路来改Mouse组件,那就是下面这样:
这样子改可以实现功能,但是复用性太差,如果有个新的功能要求也要追踪鼠标当前坐标,总不能再去改Mouse组件内部的代码吧?
所以为了复用性考虑,我们可以使用renderprops的办法来组合代码,重写上面Plane组件功能代码如下:
可以看出来这种组合代码的方式避免了直接修改Mouse组件代码,而是把它内部渲染的组件以函数的形式传进去,增强Mouse组件内部逻辑的复用性
在我看来大部分高阶组件的功能完全可以使用renderprops来实现,没有特别大的区别
总结
其实在高阶组件和renderprops之前,出现过其他复用逻辑的方式,比如mixin这种混入的模式,但也因为不够优雅逐渐被淘汰了
如果你是现在才开始学习使用React,那么我建议你直接使用Hooks来完成逻辑复用,忘掉高阶组件和renderprops吧
转载自:https://juejin.cn/post/7371717387829542953