Skip to content

一般怎么做代码重构?

代码重构是一项持续优化的过程,通常涉及 提升代码质量、优化架构、提高可维护性

一般的重构步骤如下:


1. 分析和评估

🛠 代码重构前,先搞清楚:

  • 代码哪些地方难维护?(如耦合严重、重复代码多)
  • 性能是否存在瓶颈?
  • 是否符合 SOLID 原则?(面向对象设计原则)
  • 是否有更好的设计模式可以优化?

工具辅助分析:

  • ESLint / Prettier → 代码风格检查
  • Webpack Bundle Analyzer → 代码体积分析
  • React DevTools / Vue DevTools → 组件层级优化
  • Lighthouse / Performance API → 性能分析

2. 确定重构范围

  • 小步重构:避免一次性改动太大,导致不可控的 Bug。
  • 优先级排序:先改影响大的部分(如核心功能、关键 API),然后再处理小的优化点。

示例

  • 糟糕的代码:多个组件重复使用相同的 fetch 逻辑
  • 优化方向:抽离 useFetch Hook / API 层
  • 改动范围:先改 1~2 个组件,验证后再推广

3. 代码拆分与优化

✅ 提取公共逻辑

问题:多个组件都在 useEffect 里写了相同的 API 请求
优化:封装成 自定义 Hook

tsx
// ✅ 抽离公共逻辑
const useFetchData = (url: string) => {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch(url).then(res => res.json()).then(setData);
  }, [url]);
  return data;
};
tsx
// 🎯 组件使用
const UserProfile = () => {
  const data = useFetchData('/api/user');
  return <div>{data?.name}</div>;
};

✅ 拆分大型组件

问题:单个组件代码太长,难以维护
优化:按照 单一职责原则 进行拆分

tsx
// 🚫 糟糕的写法:组件职责过多
const ProfilePage = () => {
  return (
    <div>
      <UserInfo />
      <UserPosts />
      <UserComments />
    </div>
  );
};
tsx
// ✅ 拆分成更小的组件
const ProfilePage = () => (
  <div>
    <UserInfo />
    <UserPosts />
    <UserComments />
  </div>
);

✅ 移除不必要的状态

问题:状态滥用,例如 Redux 里存放临时 UI 状态
优化:尽量用 useState 本地管理,避免全局状态污染

tsx
// 🚫 不好的做法:Redux 里存 UI 状态
const showModal = useSelector(state => state.ui.showModal);
tsx
// ✅ 只在组件内部管理
const [showModal, setShowModal] = useState(false);

4. 代码规范 & 工具集成

1️⃣ 使用 ESLint + Prettier 统一代码风格

json
{
  "extends": ["eslint:recommended", "plugin:react/recommended", "prettier"],
  "rules": {
    "no-console": "warn",
    "react/prop-types": "off"
  }
}

2️⃣ 使用 TypeScript 提高可维护性

ts
type User = {
  id: number;
  name: string;
};

const getUser = async (): Promise<User> => {
  return { id: 1, name: 'Alice' };
};

3️⃣ 使用 Husky + lint-staged 进行 Git Hook 代码校验

bash
npx husky add .husky/pre-commit "npx lint-staged"
json
{
  "lint-staged": {
    "*.ts": ["eslint --fix", "prettier --write"]
  }
}

5. 逐步替换老旧技术

1️⃣ 移除 class 组件,改为 Function Component + Hooks

tsx
// 🚫 旧写法(Class 组件)
class Counter extends React.Component {
  state = { count: 0 };
  render() {
    return <button onClick={() => this.setState({ count: this.state.count + 1 })}>{this.state.count}</button>;
  }
}
tsx
// ✅ 新写法(Hooks)
const Counter = () => {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
};

2️⃣ 使用 React Query 取代 useEffect + useState

tsx
// 🚫 旧方式:手写 fetch 请求
useEffect(() => {
  fetch('/api/data').then(res => res.json()).then(setData);
}, []);
tsx
// ✅ 现代方式:使用 React Query
const { data } = useQuery('fetchData', () => fetch('/api/data').then(res => res.json()));

6. 性能优化

1️⃣ 避免不必要的渲染

  • 使用 memo 优化纯组件
  • 使用 useCallback & useMemo 避免不必要的重新计算
tsx
const MemoizedComponent = React.memo(({ value }) => {
  console.log('组件渲染');
  return <div>{value}</div>;
});

2️⃣ 代码拆分(Code Splitting)

  • 按需加载路由
  • 使用 React.lazy + Suspense
tsx
const LazyComponent = React.lazy(() => import('./Component'));

<Suspense fallback={<div>Loading...</div>}>
  <LazyComponent />
</Suspense>;

3️⃣ 减少 re-render(优化 Context)

tsx
const UserContext = createContext();
const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  return <UserContext.Provider value={{ user, setUser }}>{children}</UserContext.Provider>;
};
tsx
const MemoizedUser = () => {
  const { user } = useContext(UserContext);
  return <div>{user?.name}</div>;
};

7. 持续迭代,保证质量

  • 代码 review:团队讨论、减少主观决策
  • 单元测试 / 集成测试:确保重构后功能正常
  • 灰度发布 / A/B 测试:降低上线风险
bash
# 运行 Jest 单元测试
npm test

题目要点:

代码重构核心思路

  1. 分析现有问题(性能、可维护性、代码风格)
  2. 小步优化(拆分组件、封装 Hook、移除冗余代码)
  3. 使用现代技术(React Hooks、React Query、TypeScript)
  4. 提升代码质量(ESLint、Husky、Prettier、测试)
  5. 性能优化(memo、lazy loading、代码拆分)
  6. 持续迭代(Code Review、A/B 测试)

如果是老项目,每次重构可以先从 关键业务模块 开始,逐步推广到整个项目