如何让React Native的useMyHook同时支持两种调用返回方式?
实现支持两种调用方式的React Native自定义Hook
需求背景
我正在开发一个React Native库,希望自定义Hook useMyHook 支持两种调用方式:
- 直接获取
show函数:const show = useMyHook() - 解构获取
show和hide函数:const {show, hide} = useMyHook()
这么做的核心原因是,当开发者仅需要show函数时,能直接自定义变量名(比如const showMyHookInBannerHomepage = useMyHook()),比解构重命名(const {show:showMyHookInBannerHomepage} = useMyHook())更简洁。
现有代码如下:
const useMyHook = () => { const MyCTX = useContext(MyContext); if (!MyCTX) { throw new Error('useMyHook must be defined.'); } // 如何实现条件返回 // return {show: MyCTX.show, hide:MyCTX.hide} // 同时支持 // return MyCTX.show return MyCTX.show; }; export default useMyHook;
可行方案
完全可以实现,这里提供两种实用方案:
方案一:给函数挂载属性
利用JavaScript中函数是一等对象的特性,直接把show函数作为返回值,同时给它挂载hide属性。这样既可以直接调用返回值作为show函数,也能通过解构获取show和hide:
const useMyHook = () => { const MyCTX = useContext(MyContext); if (!MyCTX) { throw new Error('useMyHook must be used within a MyContext provider.'); } // 复用上下文里的show函数 const show = MyCTX.show; // 给show函数挂载hide属性 show.hide = MyCTX.hide; // 同时给show函数挂载自身作为show属性,满足解构需求 show.show = show; return show; }; export default useMyHook;
方案二:使用Proxy代理对象
创建包含show和hide的对象,通过Proxy让这个对象可以被当作函数调用(调用时执行show方法)。这种方式语义更清晰,返回值本质是对象,同时具备函数调用能力:
const useMyHook = () => { const MyCTX = useContext(MyContext); if (!MyCTX) { throw new Error('useMyHook must be used within a MyContext provider.'); } const hookResult = { show: MyCTX.show, hide: MyCTX.hide }; // 用Proxy实现对象的函数调用能力 return new Proxy(hookResult, { apply(target, thisArg, args) { // 当被当作函数调用时,执行show方法 return target.show(...args); } }); }; export default useMyHook;
方案对比
- 方案一:代码简洁,无额外性能开销,但函数挂载属性的写法语义上稍显特殊。
- 方案二:语义清晰,返回值本质是包含完整API的对象,同时支持函数式调用,兼容性上React Native的Hermes引擎完全支持Proxy。
内容的提问来源于stack exchange,提问作者flix
相关产品推荐
相关产品推荐

