自定义 Hook 复用的是逻辑还是状态?

先理解原理和示例,再练习完整口述与追问。

通常复用逻辑,每次调用有独立 Hook 状态;只有显式使用共享外部存储等方案才共享数据。封装时明确输入、依赖、返回值和清理,不隐藏调用者必须理解的副作用。

自定义 Hook 复用的是一段有状态逻辑的组织方式,每个调用位置仍拥有自己的 Hook 状态。共享状态必须通过共同的上层实例、Context 或外部 store 显式建立。Hook 接口要明确输入依赖、返回值、错误与清理,调用方才不会把看似相同的两个调用误认为同一个数据源。

两个组件分别调用 useCounter,默认各有自己的 count;一个增加不会自动让另一个增加。若两处必须显示同一购物车,应把购物车放到共同 Provider 或外部 store,然后 Hook 只封装访问该共享源的方式。请求 Hook 也要决定缓存键、去重范围与结果过期规则,而不是靠模块变量偷偷共享。

把普通函数改名为 useXxx 不会自动增加状态隔离或共享。Hook 仍需顶层稳定调用,返回的取消函数和订阅清理也应纳入契约。

自定义 Hook 复用的是状态逻辑,每次在组件中调用通常获得独立的一组 Hook 状态。两个组件都调用 useCounter,并不会自动共享计数。真正共享可以通过状态提升、Context 或外部 store。Hook 应明确输入、返回值、副作用和清理,不依赖调用方猜测内部何时会请求或重置。

面试官可能继续问追问与完整解答展开收起

两个组件都调用 useCounter,计数会同步吗?useRequest 怎么避免旧响应覆盖新结果?

两个独立 useCounter 默认不会同步,除非显式读写同一外部存储。useRequest 需要给请求标记身份,在依赖变化和卸载时取消或失效旧任务,并让只有最新任务能更新其结果及 loading。