复杂业务逻辑Hook调试踩坑记录
最近在重构一个电商订单管理系统的Hook时,遇到了一个典型的复杂业务逻辑调试问题。项目中有一个useOrderProcessing Hook,需要同时处理订单状态变更、库存扣减、消息推送等多个异步操作。
问题复现步骤
- 创建订单时调用Hook,传入订单数据
- Hook内部需要依次执行:验证订单信息 → 扣减库存 → 更新订单状态 → 发送通知
- 某次测试发现,当库存不足时,订单状态竟然被更新了,但消息推送却失败了
核心Bug分析
最初代码结构如下:
const useOrderProcessing = (orderData) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const processOrder = async () => {
setLoading(true);
try {
await validateOrder(orderData);
await reduceInventory(orderData.items);
await updateOrderStatus(orderData.id, 'PROCESSING');
await sendNotification(orderData.customerId, 'order_processed');
} catch (err) {
setError(err);
// 问题:这里没有回滚已执行的操作
} finally {
setLoading(false);
}
};
return { processOrder, loading, error };
};
解决方案
通过引入事务性处理和错误回滚机制,最终重构为:
const useOrderProcessing = (orderData) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const processOrder = async () => {
setLoading(true);
let rollbackActions = [];
try {
await validateOrder(orderData);
const inventoryResult = await reduceInventory(orderData.items);
rollbackActions.push(() => restoreInventory(inventoryResult));
await updateOrderStatus(orderData.id, 'PROCESSING');
rollbackActions.push(() => revertOrderStatus(orderData.id));
await sendNotification(orderData.customerId, 'order_processed');
// 清空回滚动作
rollbackActions = [];
} catch (err) {
// 执行回滚操作
for (const rollback of rollbackActions.reverse()) {
try { rollback(); } catch (rollbackErr) { console.error('Rollback failed:', rollbackErr); }
}
setError(err);
} finally {
setLoading(false);
}
};
return { processOrder, loading, error };
};
性能优化建议
- 使用
useCallback缓存回调函数,避免不必要的重新渲染 - 对于耗时操作,考虑使用
useMemo进行计算结果缓存 - 合理使用
React.memo包装依赖Hook结果的组件
这个案例让我深刻体会到,在复杂业务场景下,Hook不仅要处理逻辑,更要考虑错误边界和数据一致性问题。

讨论