如何从React自定义Hook返回名称可动态调整的布尔值
问题根因
当前代码存在3个核心问题导致不符合预期:
- 返回对象的属性名固定写死为
isGreaterThan,没有做动态拼接 - 属性值错误赋值为拼接后的字符串,没有返回
useMediaQuery实际输出的布尔匹配结果 - 未对传入的断点key做格式化处理,传入全大写/全小写key时无法生成符合小驼峰规范的属性名,同时缺少TS类型推导,调用时无法获得动态属性的类型提示
可直接运行的实现代码
import { Breakpoint, useMediaQuery, useTheme } from "@mui/material"; // 字符串首字母大写、其余字符小写的格式化工具 const formatKey = (input: string | number) => { const str = String(input); return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); }; export const useResponsiveKey = <T extends number | Breakpoint>(key: T) => { const theme = useTheme(); const isMatch = useMediaQuery(theme.breakpoints.up(key)); const dynamicPropName = `isGreaterThan${formatKey(key)}` as const; return { [dynamicPropName]: isMatch, } as Record<typeof dynamicPropName, boolean>; };
使用方式
// 传入'md',获得isGreaterThanMd属性 const { isGreaterThanMd } = useResponsiveKey('md'); // 传入'XS',自动格式化为isGreaterThanXs属性 const { isGreaterThanXs } = useResponsiveKey('XS'); // 传入数字断点,获得对应属性 const { isGreaterThan1200 } = useResponsiveKey(1200);
实现说明
- 通过ES6计算属性语法
[dynamicPropName]动态生成返回对象的键,彻底解决属性名固定的问题 formatKey工具会自动处理输入key的大小写,无论传入xs/XS/xS,最终都会生成Xs后缀,符合小驼峰命名要求- 加入TS泛型和常量断言,调用Hook时TS可以自动推导返回的动态属性名,不会报属性不存在的类型错误
- 直接将
useMediaQuery返回的布尔值作为动态属性的值,符合Hook的响应式逻辑
内容的提问来源于stack exchange,提问作者maxfromgermany
相关产品推荐
相关产品推荐

