TypeScript+React中对象遍历取值、状态初始化及类型报错求解
问题1:初始化全false值的appliedFilters状态
数字枚举在TS中存在双向映射特性,直接遍历枚举键会同时拿到数字、字符串两类键,先过滤出我们定义的字符串形式枚举键,再通过reduce生成初始对象即可,状态初始化时直接传入该对象,避免状态为undefined:
type FiltersInComponent = { [key in FilterId]: boolean }; // 生成全false初始值 const initialFilters = Object.keys(FilterId) .filter(key => isNaN(Number(key))) // 排除数字枚举反向生成的数字键 .reduce((acc, key) => { acc[key as FilterId] = false; return acc; }, {} as FiltersInComponent); // 初始化状态,传入初始值后不需要额外处理undefined场景 const [appliedFilters, setAppliedFilters] = React.useState<FiltersInComponent>(initialFilters);
该写法会自动适配枚举后续新增/删除的项,不需要手动维护对象结构。
问题2:遍历对象渲染复选框的类型报错修复
报错核心原因是TS默认将Object.keys()的返回值推导为string[]类型,字符串无法直接作为严格类型对象的索引,同时原代码存在两个隐患:遍历项未绑定React要求的key属性、空标签无法传递key参数。
正确实现代码如下:
{Object.keys(appliedFilters) // 通过类型谓词告诉TS过滤后剩余的key是合法的枚举键 .filter((key): key is FilterId => { return typeof FilterId[key as keyof typeof FilterId] === 'number'; }) .map((filterKey) => { const isChecked = appliedFilters[filterKey]; return ( // 空标签无法传key,改用React.Fragment绑定唯一key <React.Fragment key={filterKey}> <Checkbox checked={isChecked} /> <Typography> {optionMessage(FilterId[filterKey])} </Typography> </React.Fragment> ); })}
优化建议
如果不需要依赖枚举的数字值特性,可以将数字枚举改为字符串枚举,从根源上消除双向映射带来的额外过滤逻辑,代码会更简洁:
enum FilterId { filter1 = 'filter1', filter2 = 'filter2', filter3 = 'filter3', filter4 = 'filter4', filter5 = 'filter5', }
改为字符串枚举后,初始化和遍历都不需要再写过滤数字键的逻辑。
内容的提问来源于stack exchange,提问作者Cruz
相关产品推荐
相关产品推荐

