谈谈 React + Redux 的可复用性

导语

业务背景介绍:腾讯云数据库产品中心 & 大数据及人工智能产品中心 前端从2016年初开始尝试 React + Redux 全家桶,期间经历了很多波折,到目前为止总共28个项目,其中有15个项目使用了该方案。

一、团队项目开发现状

目前团队这边各个项目都采用模块化开发,一般来说一个页面是一个模块,一个页面模块可依赖多个其他模块,然后前端通过ModuleJS识别入口文件依赖关系来加载对应的模块。

图:页面渲染流程

由于腾讯云数据库会有很多种,如:mysql, postgresql, greenplum, tdsql, sqlserver等,大数据也有很多组件,如:HBase、EMR,DataPipeline 等,直接导致了会有很多新项目需要搭建开发(如上文所述的28个项目,并且还在持续增长中),所以这里开发新项目采用的方案是部分组件复用,部分代码横向复制。

图:新项目开发模式

如上图所示, React组件模块 和 公共模块是被复用的,ModuleJS会加载同一个js模块。在一个新项目中,页面模块中的代码是被复制过去的,其中包括 React 耦合业务的代码以及 Redux 的ActionCreator 和 Reducers。

在项目数量较少的情况下这一般没有什么问题,但是当要维护的项目数量过多,其中的页面模块的重复代码就会越来越多。

特别是腾讯云官网控制台有个特点,基本上每个组件的控制台都有表格,而表格的渲染、加载、刷新、分页逻辑 和 状态树都分散在React 业务组件、Redux ActionCreator 和 Reducers 里面,这直接导致大量的重复代码,特别是当表格产生一个BUG或者要进行一次优化,均需要对多个项目均完成改造,这直接导致项目的不可维护。

二、React + Redux 业务层复用方案

上述所述,团队开发方式中存在的一个本质问题就是缺乏 React + Redux 业务层模块的复用。调研了一下React + Redux 相关社区,发现并没有适合我们团队的轮子,所以决定造一个。

图:ReactRedux Modules 方案 —— Remod

Remod 针对业务层模块打包方案,这里核心要解决的问题有以下几点:

  • 打包标准化
  • 参数控制
  • 依赖管理
  • Redux状态隔离

1、打包标准化

标准化打包是一个模块定义的必须,也是模块之间的互相引用注册的前提。这里通过定义业务模块的构成标准,如上图所示,每个Remod都由四部分构成。

  • Token 用于表示挂载Redux状态子树的Key
  • DefaultOptions 用于表示参数传递的默认参数,这里参数主要用来控制Remod Module的行为,还有一些事件回调
  • Dependencies 表示当前 Remod Module依赖的 Remod Module 列表
  • React+Redux Code 表示当前 Remod Module 的 React+Redux业务代码

2、参数控制

一个业务层模块与React组件类似,是可以随着其他业务引用方的需要可以自由配置的,其提供的参数能够实现下面三种类型传递

  • 基础属性 用于控制业务层模块的表现(表格举例 如:是否显示新建按钮,表格加载的数据接口)
  • 事件回调 用于控制业务层模块事件行为(表格举例 如:新建按钮点击事件触发回调,表格数据加载后数据加工处理回调)
  • 事件触发 用于获取业务层模块事件触发器(actions),使得引用方能够主动触发被引用模块的一些事件行为

3、依赖管理

多个业务层模块之间,肯定会存在一些依赖关系,如:模块A引用模块B,模块B引用模块C、模块D。当每个业务层模块都申明了自己的依赖之后,那么在模块A被引用的时候,就可以自动计算出它所有依赖的:

  • 模块A Redux Reducer
  • 模块B Redux Reducer
  • 模块C Redux Reducer
  • 模块D Redux Reducer

并将上述Reducer均注册到Redux Store。

4、Redux状态隔离

Redux状态隔离指的是每个业务层模块只能更新自己Token下面的状态子树,这样业务层模块职责单一,高内聚低耦合,在复杂的情况下代码不会出现难以维护的情况。

三、核心原理

Remod在React Redux框架中的运用如下图所示,其中蓝色部分是 Remod的核心。特别要说明的是,QMRR组件是使用Remod框架输出的可复用业务层组件,该组件包含React 业务组件与Redux 相关业务层代码,与传统Page不同的是,使用了Remod内置的connect方法延迟连接到Redux Store, 真正connect操作在 Page引用该业务层组件的时候完成。

图:Remod运用在React Redux框架中的架构图

另外,Remod对Thunk做了改造,使得封装的 QMRR组件 (RemodModule)只能将action dispatch 到自己的状态子树上面去,如上图的 auto-reducerA状态子树处理逻辑。同时考虑到老业务的无缝兼容引用,这里 TokenThunk 也兼容了 thunk 原生 dispatch 写法。

AutoReducer 是 Remod 另一特色,该模块能够创建自动化的 Redux Reducer 处理器,使得开发人员不用写 Reducer 代码,提升工作效率。

QCR 组件在这里是React的基础公共组件。

Remod connect原理如下图所示:

图:Remod connect原理

要弄明白Remod connect的实现原理,先要了解 React-Redux 的原理。React-Redux是通过connect方法将React组件绑定到Redux,该方法返回一个WrappedComponent,WrappedComponent包装了当Redux状态变化的对React组件的处理逻辑。

Remod connect的原理是在WrappedComponent基础上再包一层对象,通过调用该对象上的配置函数来得到一个WrappedComponent来实现Redux的延迟绑定,而该对象包含了依赖信息,参数控制等信息。

四、实践效果

15个项目中7个项目已接入,并取得下面成功

  • 提升开发效率,已将 Reducer 代码全部优化掉
  • 提升开发效率,表格页面开发效率从1天提升到1小时
  • 减少样板代码,CLOC统计模块代码量减少约 15.3%
  • 减少重复代码,CLOC统计项目代码量平均减少约 50.2%
  • 高可维护,在线修复bug或优化升级
  • 成功节约大量开发和维护成本,开发更便捷更规范化

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

【专业技术】Chromium浏览器组件是咋设计出来的?

在文章开始之前,我要叽歪几句,一上来就看chrome的代码,简直晕头转向,摸来摸去摸不着头脑,好不容易看了一点点代码,却宛如瞎子摸象,无法众观全局,下面这篇小文...

3256
来自专栏思考的代码世界

Python网络数据采集之登录采集处理|第08天

如果我们采集的网站需要我们登录后才能获取我们想要的数据,这就需要进一步处理登录这个问题。

4027
来自专栏Java进阶架构师

dubbo源码解析-详解directory

由于明天还要加班(心疼自己一秒),之前答应过小伙伴每周更新一篇dubbo的源码解析的,鉴于上次讲到了集群容错的总体架构,这次主要讲讲第一个关键词director...

735
来自专栏云飞学编程

Python爬虫!老司机详解爬虫,你想爬的都在这里

推荐下小编的Python学习群5421107414,不管你是小白还是大牛,小编我都欢迎,欢迎初学和进阶中的小伙伴。

522
来自专栏有趣的Python

(旧)3- Flask构建弹幕微电影网站- 课程介绍Flask 构建微电影视频网站

Flask 构建微电影视频网站 已上线演示地址: http://movie.mtianyan.cn 项目源码地址:https://github.com/mti...

3869
来自专栏腾讯IVWEB团队的专栏

使用Yeoman generator来规范工程的初始化

本文分为两部分,首先会谈谈目前团队的痛点以及基于yeoman generator的设计思路;然后会详细介绍如何实现定制的generator,过程中遇到的问题和解...

1430
来自专栏企鹅号快讯

SEO×静态、动态、伪静态URL的特性

1、静态页面 优点:相比其他两种页面,速度最快。不仅仅是秒杀秒客网加载速度最快,而且不需要从数据库里面提取数据,速度快的同时,也不会对服务器产生压力。 缺点:由...

1968
来自专栏小詹同学

老司机带你用python来爬取妹子图

这是小詹关于爬虫的第③篇文章! 这篇文章来自一个大一学弟的公众号「日常学python」 虽然这篇文章难度不大,但是对新手来说绝对是福利,爬天爬地爬空气你懂得~ ...

3687
来自专栏Linyb极客之路

API设计:先思考再编码

783
来自专栏小白课代表

最优秀好用的免费文件压缩/解压缩工具软件

若常常需要与 Mac 用户交换文件,或是购买一些国外的数字商品(如我购买的日本同人志),常常会遇见压缩包打开是一片一片的乱码文件名的状况。编码问题一直是造成乱码...

551

扫码关注云+社区