日常开发为什么需要做Code Review
日常开发为什么需要做Code Review

一、背景
最近在开始一个新的项目,在查看项目中代码及具体细节时,发现这个项目真实一堆乱麻,没有规律可循,可总结下这个项目的缺陷
- 没有规律可循,没有结构性设计
- 不做公共封装,哪里方便哪里创建变量
- 一个个文件大于300行,都是超大文件,组件中方法超大逻辑
- class组件部分逻辑可继承封装,但是采取了复制粘贴相同代码的处理
看的我是一堆乱麻,不由得让我开始思考,程序员果真是懒,如果再勤快一些,可能会进行代码的封装和考虑这些公用方法及组件的抽取,同时也存在项目中Code Review 的缺失。
二、为什么需要Code Review 及优点
看这些奇奇怪怪的代码,不由得让我拍脑袋直言,当初多进行进行Code Review ,将这些问题屏蔽掉至少,那Code Review 有哪些优点呢
进行代码审查的原因可以归结为以下几点:
-
提高代码质量: 可以帮助开发者更好地编写代码,减少错误和缺陷,提高代码的质量和可维护性。通过Code Review ,开发者可以识别并修复潜在的问题,从而提高代码的可靠性和稳定性。
-
减少错误率:通过代码审查,开发人员可以发现之前可能没有注意到的错误或缺陷,从而减少错误的发生。
-
促进团队协作: 可以帮助团队成员之间更好地协作,不仅仅是老员工之间的协作,而且更加有效的帮助新员工融入到团队中,确保代码的一致性和可重用性。通过 Code Review ,开发者可以更好地理解其他开发者的代码,并从中学习,从而提高自己的编程水平。
-
提高开发效率: 可以帮助开发者更快地完成任务,减少代码编写的时间。通过 Code Review ,开发者可以更快地发现和解决问题,从而减少调试的时间和工作量。
-
确保代码符合规范: 可以帮助开发者遵循团队的代码规范,确保代码的可读性和可维护性。这对于大型项目的开发非常重要,因为遵循规范可以帮助开发者更好地协作和理解代码。
综上所述,Code Review 对于前端开发的质量和效率都非常重要。通过 Code Review ,开发者可以更好地编写代码,提高代码的质量和可维护性,促进团队协作,提高开发效率和确保代码符合规范。
三、Code Review 都有哪些方式
总体来说可分为常规代码Code Review 和 阻断式Code Review
- 常规代码Code Review
提出修改建议与检查,不阻断代码合并或者影响开发者其他进度的检查
通常这种检查会是团队成员聚集在一起,听其他成员讲述自己最近的开发代码。 - 阻断式Code Review
需要合并进主分支等,需要必须要求复合规定时的检查,必须等待处理完所有建议或者不符合规定的点之后才能合并进主分支
四、Code Review 都会去注意哪些点
既然要做Code Review,那应该去检查哪些细节,我举个我开发中遇到的一些例子,给大家打个样,开发层更多地涉及到React Native中的一些知识点,可以选择性的阅读。
-
代码是否按照lint规范提交,以及其他约定的一些规范提交
至关重要的检查,lint可以省掉很多review内容,可能有时,一些比较着急的开发者会提交代码时使用
-n命令忽略检查进行提交 -
useSelector使用规则,优化页面性能
使用redux的同学可能会知道,useSelector会导致页面重新渲染,这边也就成为了日常review的一项const kfo = useSelector((state) => state.AtReducer.kfo || {});不规范原因: useSelector 底层是使用 === 比较 此处|| {}代码逻辑上容易触发render更新;
建议改为以下写法const kfo = useSelector( (state) => state.AtReducer.kfo ) || {}使用useSelector时也需要关注state的粒度,导出自己需要的变量,不要一下子导出state.userInfo整个变量,同时使用shallowEqual进行比对处理
const { username, age } = useSelector(state => { const { username, age } = state.userInfo;return { username, age }; }), shallowEqual); -
不要出现大文件,大文件增加分组进行拆分,按照业务模块分组或者extends继承机制处理
超过1000行的文件出现bug,你会去看吗?你会很轻松的找到问题所在吗?答案肯定是不会,因为那么多行代码需要检查,而且也没有信息完全肯定能够修改正常,那肯定得避免出现这种文件,方便自己以及后面有其他同事接手这个项目时,能够不会有那么多的心理负担「🐶」
-
双map或forEach遍历时,可能需要考虑优化
出现这种情况的常见算法一般都是先找出数组中固定的某一个值,然后在用这个值去做业务逻辑,这样可能得和业务人员确定是否存在更加优化的处理方案,比如下面是用了es6中结构赋值的方案去减少了一次检索的过程,这种双循环的,一般都仔细检查下看看是否有优化方案
// 使用解构赋值的模型,减少map循环的使用 (lists || []).map(({ person: name }) => {// 使用name在进行处理其他业务逻辑// name }) -
默认的空赋值[]或者{}
正常来说,比如子组件的userList属性规定类型是数组,在父组件加工数据时提供数据默认值是非常好的习惯,于是我常常在组件内部或者mapStateToProps中看到类似的写法:
const App = (props) => { // 当存在时赋予空数组,保证下层数组类型的正确性 const userList = props.userList || []; return (<Child userList={userList} />) };当App多次渲染且props.userList为假值时,此时的userList也会被不断的赋予全新的空数组。还记得前文说的吗,当你结构没变化时,我们保证其引用不变不就好了,所以对于空数组都可以在全局赋予一个空数组,比如:
const emptyArr = []; const App = (props) => { // 当存在时赋予空数组,保证下层数组类型的正确性 const userList = props.userList || emptyArr;return (<Child userList={userList} />) };这样不管App如何渲染,当userList被赋予为空数组时也能让前后引用相同。
-
使用 DeviceEventEmitter.addListener( ‘CHANGE’, function () {})注意依赖的项目可能不为最新值问题
const ref = useRef();const listenerChange = () => {dispatch(FetchConfig({ jwtKey: userInfo?.jwtKey }, (dataList) => {setKols(dataList);}));}ref.current = listenerChange;useEffect((): function => {const listener = DeviceEventEmitter.addListener('CHANGE',function () {ref.current?.();})return () => {listener?.remove?.();};}, []);如果参数存在于延迟setTimeout,同时依赖于变量,也需要考虑通过以上方案处理,看看下面栗子🌰
const [jwt] = useState('');setTimeout(() => {DeviceEventEmitter.emit('send',{ jwt: jwt }) }) -
addListener事件命名建议采用【模块_特性_名称】,采用全局较为统一的规范
如:LOGIN_STATUS_CHANGE,LOGOUT_STATUS_CHANGE -
使用useFocusEffect注意配合使用useCallback,否则会造成多次渲染
-
默块引入使用路径别名,抽取行内样式
-
Platform.select 和 Platform.OS区分,针对平台比较复杂的逻辑,使用平台判断Platform.select的方案处理
-
react-native元素标签逻辑判断问题
isShow逻辑判断使用!!isShow转义后进行使用,否则会提示文本必须在Text元素中使用的提示信息<View style={styles.fastContainer}>{!!isShow && <View></View>} </View> -
使用setTimeout、setInterval等伪代码时,需要在组件卸载时或关闭操作时将其清除掉
● setTimeout的销毁函数为clearTimeout
● setInterval的销毁函数为clearInterval
对于多次打开的setTimeout,setInterval需要在再次开启时清空其值clearmyTime: () => void = () => {// eslint-disable-next-lineif (!!this.myTimeout) {clearTimeout(this.myTimeout);this.myTimeout = null;} };onSelected = () => {// 每次开启新的延迟计时器时,都进行清空操作this.clearmyTime();this.myTimeout = setTimeout(() => {// 操作}, 1000) } -
数组遍历需要考虑使用useMemo处理
map,filter等方法,以及lodash中的遍历方法,都需要使用useMemo进行处理 -
数值类比较操作
receive < 0 ? 0 : receive,可以考虑使用数学方法const value = receive < 0 ? 0 : receive; // 等同于 const value = Math.max(receive, 0); -
保证key唯一,不要使用数组遍历产生的index,方便虚拟dom diff,提升性能

相关文章:
日常开发为什么需要做Code Review
日常开发为什么需要做Code Review 一、背景 最近在开始一个新的项目,在查看项目中代码及具体细节时,发现这个项目真实一堆乱麻,没有规律可循,可总结下这个项目的缺陷 没有规律可循,没有结构性设计不做公共封装&#…...
OSPF的优化
O_ASE --- 标志域外路由信息 --- 因为域外的路由信息不可控性较强,所以,信任程度较低,我们将其优先级设置为150。 LSA --- 链路状态通告 --- OSPF协议在不同网络环境下产生的用于携带和传递不同的信息。 LSDB --- 链路状态数据库 SPF --- 最短…...
C++项目中打破循环依赖的锁链:实用方法大全
C项目中打破循环依赖的锁链 一、简介(Introduction)1.1 循环依赖的定义(Definition of Circular Dependencies)1.2 循环依赖带来的问题(Problems Caused by Circular Dependencies)1.3 解决循环依赖的重要性…...
IDEA连接HBase
新建maven工程 打开pom.xml添加hbase需要的依赖 <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.3.5</version> </dependency><dependency><groupId>org.apa…...
Mask2Former来了!用于通用图像分割的 Masked-attention Mask Transformer
原理https://blog.csdn.net/bikahuli/article/details/121991697 源码解析 论文地址:http://arxiv.org/abs/2112.01527 项目地址:https://bowenc0221.github.io/mask2former Mask2Former的整体架构由三个组件组成: 主干特征提取器ÿ…...
【量化课程】01_投资与量化投资
文章目录 1.1 什么是投资1.1.1 经济意义上的投资1.1.2 投资的分类1.1.3 金融投资1.1.4 个人投资者投资品种1.1.5 投资VS投机 1.2 股票投资的基本流程1.3 常见的股票投资分析流派1.3.1 投资者分析流派 1.4 什么是量化投资1.4.1 量化投资基本概念1.4.2 量化投资的优势1.4.3 量化投…...
SpringBoot实现导出Excel功能
1 问题背景 需求要做一个导出excel的功能 2 前言 本篇着重阐述后端怎么实现,前端实现的部分只会粗略阐述。该实现方案是经过生产环境考验的,不是那些拿来练手的小demo。本文阐述的方案可以借鉴用来做毕设或者加到自己玩的项目中去。再次声明,…...
NSSCTF之Misc篇刷题记录⑧
NSSCTF之Misc篇刷题记录 [MMACTF 2015]welcome[广东强网杯 2021 团队组]欢迎参加强网杯[虎符CTF 2022]Plain Text[SWPUCTF 2021 新生赛]原来你也玩原神[SWPUCTF 2021 新生赛]我flag呢?[鹤城杯 2021]New MISC NSSCTF平台:https://www.nssctf.cn/ PS&…...
从零开始学习Linux运维,成为IT领域翘楚(七)
文章目录 🔥Linux下常用软件安装_JDK和Tomcat安装🔥Linux下常用软件安装_MySQL安装🔥Linux下常用软件安装_MySQL卸载 🔥Linux下常用软件安装_JDK和Tomcat安装 Jdk 安装 解压jdk安装包 tar -zxvf jdk-8u201-linux-x64.tar.gz -C/…...
优漫动游设计APP的UI界面需要注意哪些问题?
一、加载 加载时间的长短,很大程度的决定了用户体验是否有所提升,虽然理想中的页面加载出来应该一秒就够了,但是设计师不要忽略网络问题!如果网速不够的话,页面加载三五秒都算是快的了,所以在用户等待的过程中&a…...
面试 004
什么是 Java 内存结构 Java 内存结构就是 JVM 的运行书数据区的内存结构: 里面有堆、虚拟机栈、本地方法栈、程序计数器; 虚拟机栈:里面的数据结构是栈帧,存放了方法名,局部变量等信息 方法区在 1.8 的时候…...
CCF-202206-2-寻宝!大冒险!
目录 题目背景 问题描述 一、思路: 二、实现方法(C) 2.1、方法一(int储存) 思路: C实现如下: 2.2、方法二(结构体储存) 思路: 注意:边界…...
二叉搜索树中的众数
1题目 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义&…...
认识JSP
什么是JSP? JSP(Java Server Pages)是一种类似于HTML的标记语言,用于创建动态Web页面。与HTML不同的是,JSP页面中可以嵌入Java代码,由Web服务器在动态页面中生成HTML代码,从而实现Web应用程序的前端交互效…...
MySQL数据管理
一、MySQL数据库管理 1、库和表 行(记录):用来描述一个对象的信息 列(字段):用来描述对象的一个属性 2、常用的数据类型 int :整型 float :单精度浮点 4字节32位 double &…...
第十九章 Unity 其他 API
本节介绍一些其他经常使用的Unity类。首先,我们回顾一下Vector3向量类,它既可以表示方向,也可以表示大小。它在游戏中可以用来表示角色的位置,物体的移动/旋转,设置两个游戏对象之间的距离。在我们之前的课程中&#x…...
sha256算法详解,用C语言模拟sha256算法
SHA-256是一种加密算法,它可以将任意长度的数据块计算出一个固定长度的输出值,通常是256位。SHA-256具有以下特点: 1. 固定输出长度:SHA-256的输出长度为256位,不受输入数据的长度限制。 2. 不可逆性:SHA-256采用单向哈希函数,即无法从输出值反向推出输入数据。 3. 抗…...
前端技术未来发展展望
前端技术在未来的发展中将继续保持快速、变化多样和创新性强的趋势。以下是我认为前端技术未来发展的几个方向: 框架和库的演进:框架和库的更新换代将继续加速。React、Vue、Angular等主流框架的更新周期将会缩短,同时各自的生态系统也将更加…...
第四十六天|dp
今天的题还是完全背包的题 139. Word Break 这道题其实用deque也能做,但是需要cache去记录之前尝试过的值,.相对简单的办法就是用完全背包了 这道题worddict就是物品.我们的dp[i]代表到i为止是不是能满足题意分成segmentation 处置化全为false,但是dp[0]True.这是因为为0时…...
汇编语言-复习自用
本文用于自我复习汇编语言,参考b站一位老师的讲解整理而成,感谢老师的无私付出视频链接链接 文章目录 1.第一章1.1计算机组成1.2读取1.3 寄存器及数据存储1.4 mov和and指令1.5 确定物理地址1.6 内存分段表示法1.7debug使用1.8CS:IP1.9jmp指令改变csip1.1…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...
