一般怎么做代码重构?
代码重构是一项持续优化的过程,通常涉及 提升代码质量、优化架构、提高可维护性。
一般的重构步骤如下:
1. 分析和评估
🛠 代码重构前,先搞清楚:
- 代码哪些地方难维护?(如耦合严重、重复代码多)
- 性能是否存在瓶颈?
- 是否符合 SOLID 原则?(面向对象设计原则)
- 是否有更好的设计模式可以优化?
工具辅助分析:
- ESLint / Prettier → 代码风格检查
- Webpack Bundle Analyzer → 代码体积分析
- React DevTools / Vue DevTools → 组件层级优化
- Lighthouse / Performance API → 性能分析
2. 确定重构范围
- 小步重构:避免一次性改动太大,导致不可控的 Bug。
- 优先级排序:先改影响大的部分(如核心功能、关键 API),然后再处理小的优化点。
示例
- 糟糕的代码:多个组件重复使用相同的
fetch逻辑- 优化方向:抽离
useFetchHook / 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题目要点:
代码重构核心思路:
- 分析现有问题(性能、可维护性、代码风格)
- 小步优化(拆分组件、封装 Hook、移除冗余代码)
- 使用现代技术(React Hooks、React Query、TypeScript)
- 提升代码质量(ESLint、Husky、Prettier、测试)
- 性能优化(memo、lazy loading、代码拆分)
- 持续迭代(Code Review、A/B 测试)
如果是老项目,每次重构可以先从 关键业务模块 开始,逐步推广到整个项目