如何在单个React组件中创建自定义useToggle钩子的多个独立实例
实现方案
你只需要给返回的数组附加对应的对象属性即可,JS中数组本身属于对象类型,支持挂载自定义属性,修改后可以同时兼容数组解构、对象解构两种使用方式。
第一步:调整类型定义(针对TReactHookUseToggle)
将类型修改为数组和对象的交叉类型,兼容两种解构方式:
// 放在@jefelewis/unison-types对应的类型文件中 export type TReactHookUseToggle = [boolean, () => void] & { isToggled: boolean; toggle: () => void; }
第二步:修改useToggle实现
// Imports: Dependencies import { useCallback, useState } from 'react'; // Imports: TypeScript Types import { TReactHookUseToggle } from '@jefelewis/unison-types'; // React Hook: Use Toggle export const useToggle = (initialState: boolean = false): TReactHookUseToggle => { // React Hooks: State const [isToggled, setIsToggled] = useState<boolean>(initialState); // Toggle const toggle: () => void = useCallback((): void => setIsToggled((prevState: boolean) => !prevState), []); // 构造返回值,同时支持数组和对象解构 const returnValue = [isToggled, toggle] as const; Object.assign(returnValue, { isToggled, toggle }); return returnValue as TReactHookUseToggle; };
使用示例
你可以任选以下任意一种调用方式,都能正常运行:
- 优先推荐的对象解构,不同实例的变量完全独立不冲突
// 隐私政策控制 const { isToggled: privacyOpened, toggle: togglePrivacy } = useToggle(); // 服务条款控制 const { isToggled: termsOpened, toggle: toggleTerms } = useToggle(); <button title="Privacy Policy" onClick={togglePrivacy} /> <button title="Terms & Conditions" onClick={toggleTerms} />
- 直接赋值为对象使用(符合你给出的期望调用写法)
const privacyPolicy = useToggle(); const terms = useToggle(); <button title="Privacy Policy" onClick={privacyPolicy.toggle} /> <button title="Terms & Conditions" onClick={terms.toggle} />
- 兼容原有数组解构用法
const [privacyOpened, togglePrivacy] = useToggle(); const [termsOpened, toggleTerms] = useToggle();
内容的提问来源于stack exchange,提问作者jefelewis
相关产品推荐
相关产品推荐

