Code Review实战:提升代码质量与团队协作效率的关键技巧

予曦 Dev 前端 阅读 2,321
赞 21 收藏
二维码
手机扫码查看
反馈

项目初期的技术选型

上个月收尾的这个后台管理系统,前端团队就三个人,工期压得紧,需求又变来变去。一开始我们连要不要做 Code Review 都犹豫过——毕竟人少、节奏快,怕拖进度。但之前另一个项目因为没 review,上线后发现好几个低级 bug,比如把 user.id 写成 user.Id,还有个循环里直接 setState 导致页面卡死。所以这次咬牙决定:哪怕再赶,也得走 review。

Code Review实战:提升代码质量与团队协作效率的关键技巧

工具选了 GitHub 的 PR(Pull Request)流程,没上 Gerrit 或其他重型系统,主要是团队都熟悉 GitHub,上手快。规则也定得简单:所有功能分支必须经过至少一人 review 才能合入 main;紧急 hotfix 也得事后补 review。说实话,开始执行时有点别扭,尤其我这种老写单干代码的人,总觉得“别人看我代码是不是在挑刺”。但几轮下来发现,其实大家更关注逻辑是否清晰、边界有没有覆盖,而不是抠格式。

最大的坑:性能问题

真正让我头疼的是一个数据表格组件的 review。同事提了个 PR,用 map 渲染上千条数据,本地跑着没问题,但测试环境一加载就卡顿。我第一反应是“分页啊”,结果他说产品要求一次性展示全部数据(别问,问就是“客户坚持”)。review 时我指出了性能隐患,但他觉得“先跑起来再说”。结果上线预发环境后,低端安卓机直接白屏。

折腾了半天发现,问题出在两个地方:一是每次状态更新都触发全量 re-render,二是每个单元格都绑了独立的事件处理器。后来我们重写了组件,用了虚拟滚动 + 事件委托。核心改动就这几行:

// 虚拟滚动容器
const VirtualList = ({ items, itemHeight, containerHeight }) => {
  const [scrollTop, setScrollTop] = useState(0);
  const visibleCount = Math.ceil(containerHeight / itemHeight);
  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = startIndex + visibleCount;

  const visibleItems = items.slice(startIndex, endIndex);

  return (
    <div
      style={{ height: containerHeight, overflow: 'auto' }}
      onScroll={(e) => setScrollTop(e.target.scrollTop)}
    >
      <div style={{ height: items.length * itemHeight }}>
        {visibleItems.map((item, index) => (
          <div
            key={startIndex + index}
            style={{
              position: 'absolute',
              top: (startIndex + index) * itemHeight,
              height: itemHeight,
              width: '100%',
            }}
          >
            {/* 渲染单个 item */}
            <DataCell data={item} />
          </div>
        ))}
      </div>
    </div>
  );
};

这里注意我踩过好几次坑:key 必须用真实索引(startIndex + index),不能只用 index,否则滚动时复用错乱;外层容器高度必须固定,不然 scrollTop 计算不准。另外,事件委托我们统一挂到父容器上,避免每个 cell 绑函数:

// DataCell 内部不再绑定 onClick
// 而是在 VirtualList 的父容器处理
<div onClick={(e) => handleCellClick(e)}>
  {/* ... */}
</div>

// handleCellClick 通过 dataset 获取行信息
const handleCellClick = (e) => {
  const rowId = e.target.closest('[data-row-id]').dataset.rowId;
  // 处理点击
};

核心代码就这几行

除了性能,另一个高频问题是 API 错误处理。早期代码里经常看到这样的写法:

// 千万别这么写!
fetch('/api/data')
  .then(res => res.json())
  .then(data => setData(data));

没 catch,没 loading 状态,网络失败直接静默。Review 时我强制要求所有异步操作必须包含错误兜底和用户反馈。后来我们封装了个简单的 hook:

// useApi.js
import { useState, useCallback } from 'react';

export const useApi = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const request = useCallback(async (options = {}) => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(url, options);
      if (!res.ok) throw new Error(HTTP ${res.status});
      const json = await res.json();
      setData(json);
      return json;
    } catch (err) {
      setError(err.message);
      console.error('API error:', err);
      // 实际项目中这里会调用 message.error() 之类
    } finally {
      setLoading(false);
    }
  }, [url]);

  return { data, loading, error, request };
};

用起来很简单:

// 在组件里
const { data, loading, error, request } = useApi('https://jztheme.com/api/users');

useEffect(() => {
  request();
}, [request]);

亲测有效,至少不会再出现“点按钮没反应”的用户投诉了。不过这个 hook 没处理重复请求取消(比如快速切换 tab),算是个小瑕疵,但目前业务场景影响不大,就没动。

踩坑提醒:这三点一定注意

  • 别让 review 变成格式战争:我们早期花太多时间争论缩进用 2 还是 4 个空格。后来直接配了 Prettier + ESLint,PR 里只讨论逻辑,格式问题交给 CI 自动 fix。
  • 新人 PR 别只说“LGTM”:有次实习生写了段防抖,但 delay 写死了 300ms,而搜索接口其实需要 500ms 才稳定。我直接 comment:“这里 delay 建议抽成常量,方便后续调整”,并附上文档链接。比单纯 approve 有用多了。
  • 大 PR 拆小:超过 500 行的 PR 基本没人细看。后来规定:功能拆成“骨架 → 逻辑 → 样式”三个 PR,review 效率高很多。

回顾与反思

搞了两个月 Code Review,整体效果不错:线上 bug 少了大概 40%,尤其是低级错误基本绝迹。团队沟通也变多了,以前各写各的,现在会主动问“你这块怎么设计的”。不过也有做得不好的地方:比如有些边缘 case 的测试覆盖还是靠自觉,没有强制要求单元测试;还有一次因为 review 太慢,阻塞了发布,后来我们加了 SLA——普通 PR 24 小时内必须响应。

方案肯定不是最优的,比如没上自动化测试集成,也没做权限分级(现在所有人能 approve 所有 PR)。但对我们这种小团队来说,简单够用就行。毕竟工期紧的时候,能快速发现问题比追求完美流程更重要。

以上是我踩坑后的总结,希望对你有帮助。如果你们有更好的 review 实践,比如怎么平衡速度和质量,欢迎评论区交流!

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论
❤怡彤
❤怡彤 Lv1
作者的分享让我学会了如何在职场中持续提升自身竞争力,为未来发展做好准备
点赞 3
2026-02-27 09:25