Apollo错误日志最佳实践:自定义Hook内还是组件中?
方案A:在Hook内统一记录日志
export const useCreateAccount() => { // 省略其他逻辑 const {loading, error, data} = useMutation(query, options); // 新增日志逻辑 if (error) { logger.error('创建账号出错', error); } // 省略其他逻辑 return [loading, data, error]; }
方案B:在调用Hook的组件内记录日志
import {useCreateAccount} from './createAccountHook.js'; export const MyComponent() => { // 省略其他逻辑 const [loading, data, error] = useCreateAccount(); // 新增日志逻辑 if (error) { logger.error('创建账号出错', error); } // 省略其他逻辑 }
最佳实践分析
方案A的优劣势
- 优点:
- 复用性强:所有调用这个Hook的组件都会自动记录错误,不用重复写日志代码,避免遗漏。
- 逻辑集中:Hook负责数据请求和通用错误处理,组件只需要专注UI层的业务逻辑。
- 日志统一:所有通过该Hook产生的错误日志格式、内容可以统一维护,排查问题时更高效。
- 缺点:
- 灵活性差:如果某个组件需要给日志加专属上下文(比如当前用户操作步骤),Hook内的统一逻辑满足不了,除非额外加配置。
- 易重复日志:如果组件重渲染时错误状态没变化,会重复打日志,需要用
useEffect监听error变化来避免。
方案B的优劣势
- 优点:
- 灵活性高:每个组件可以根据自身场景给日志加专属信息,让日志更有针对性。
- 按需记录:组件可以自主决定是否记录错误,或者只记录特定类型的错误,不会强制所有调用方都打日志。
- 缺点:
- 代码冗余:每个使用Hook的组件都要重复写错误判断和日志代码,团队协作时容易遗漏。
- 日志混乱:不同组件可能用不同的日志描述、格式,后期排查问题时增加复杂度。
推荐选择
如果项目中大部分场景的错误日志需求是统一的,优先选方案A,但要做两点优化:
- 用
useEffect监听error变化,确保只有错误新增时才记录,避免重复日志:
export const useCreateAccount() => { // 省略其他逻辑 const {loading, error, data} = useMutation(query, options); useEffect(() => { if (error) { logger.error('创建账号出错', error); } }, [error]); // 省略其他逻辑 return [loading, data, error]; }
- 给Hook加可选配置项,允许组件自定义错误处理,兼顾灵活性:
export const useCreateAccount({onError} = {}) => { // 省略其他逻辑 const {loading, error, data} = useMutation(query, options); useEffect(() => { if (error) { // 优先使用组件传入的自定义处理,没有则用默认日志 onError ? onError(error) : logger.error('创建账号出错', error); } }, [error, onError]); // 省略其他逻辑 return [loading, data, error]; }
这样既保留了方案A的复用性和统一性,又能满足特殊场景的定制需求。
如果项目中每个组件的日志需求差异很大,或者只有少数组件需要记录日志,那方案B更合适。
内容的提问来源于stack exchange,提问作者quirk worx
相关产品推荐
相关产品推荐

