Recompose迁移React Hooks适配React17:compose替换方案
recompose 中 compose 的作用与移除适配方案 compose 的实际作用
compose 是标准的函数组合工具,核心作用是按从右到左的顺序嵌套执行传入的多个高阶组件(HOC),替代多层HOC手动嵌套的写法,避免代码缩进过深的问题。
以你给出的代码为例:
import { withRouter } from 'react-router'; import { compose } from 'recompose'; import App from './App'; import { InnerProps, OuterProps } from './App.types'; import withAppCookie from './with-app-cookie'; export default compose<InnerProps, OuterProps>(withRouter, withAppCookie)(App);
这段代码和下面手动嵌套HOC的运行逻辑100%等价:
export default withRouter(withAppCookie(App));
代码里传入的两个泛型作用分别是:
InnerProps:所有HOC注入完成后,最终传递给内部App组件的属性类型OuterProps:外部调用最终导出的组件时,需要手动传入的属性类型
执行时会先把App传入withAppCookie拿到一层包裹后的组件,再把这个组件传入withRouter拿到最终导出的组件,和手动嵌套的执行顺序完全一致。
移除recompose后的适配方法
由于项目中只用到了compose这一个API,不需要引入额外的重型依赖,可根据项目实际情况选以下任意一种方案:
方案1:直接手动嵌套HOC(改造成本最低)
如果项目中compose的调用点很少,直接删除compose相关代码,改成手动嵌套HOC即可,改完的App.container.ts代码如下:
import { withRouter } from 'react-router'; import App from './App'; import withAppCookie from './with-app-cookie'; export default withRouter(withAppCookie(App));
如果需要保留TS类型校验,直接复用原有InnerProps、OuterProps类型给导出组件做声明即可,功能和原代码完全一致。
方案2:自行实现通用compose(适合调用点多的场景)
如果项目中有大量地方用到了recompose的compose,逐个修改嵌套成本太高,可以在项目公共工具目录下实现一个极简版compose,替换所有recompose的compose导入即可。
极简compose实现代码:
// 存放路径示例:src/utils/compose.ts type AnyFunc = (...args: any[]) => any; export default function compose<T extends AnyFunc>(...funcs: AnyFunc[]): T { if (funcs.length === 0) return ((arg: any) => arg) as unknown as T; if (funcs.length === 1) return funcs[0] as T; return funcs.reduce((composed, current) => (...args: any[]) => composed(current(...args))) as T; }
替换时只需要把原有代码里的import { compose } from 'recompose'改成import compose from '你的工具路径/compose'即可,原有业务代码、TS泛型写法不需要做任何改动,执行逻辑和recompose的compose完全对齐。
补充:如果项目本身已经引入了Redux,可以直接使用Redux内置的
compose方法,不需要自行实现,直接修改导入语句为import { compose } from 'redux'即可,用法完全一致。
内容的提问来源于stack exchange,提问作者meez

