如何通过组件名称正确创建并渲染React组件?解决TS报错
解决动态渲染React组件的TypeScript错误及规范实现
当前错误的修复
1. 修正返回类型错误
你的getFormatter函数返回类型写的是React.Component,这是组件的实例类型,但JSX需要的是组件的构造函数/函数类型(即React.ComponentType)。将返回类型修改为React.ComponentType<any>(若需要更严谨的类型约束,可自定义props类型):
function getFormatter(type: string, name: string, meta: JsonApiMetaAttributeType): React.ComponentType<any> { let formatterName = capitalizeFirstLetter(meta[type][name].type) + 'Formatter' if (!isFormatterKey(formatterName)) { formatterName = 'StringFormatter' } return Formatter[formatterName] }
2. 修正JSX标签笔误
代码中</FormatterComponent2>是笔误,需改为</FormatterComponent>:
{ Object.keys(item.attributes).map((attrName: string) => { const FormatterComponent = getFormatter(item.type, attrName, meta) return ( <td key={"data-cell-" + attrName}> <FormatterComponent> {item.attributes[attrName]} </FormatterComponent> </td> ) }) }
规范的动态组件渲染模式
1. 明确组件映射与类型约束
单独定义组件映射对象,配合TypeScript类型系统约束可用组件,让类型检查更严格:
// 定义Formatter组件的通用props类型 type FormatterProps = { children: React.ReactNode; // 可添加其他通用props字段 }; // 定义组件映射类型 type FormatterMap = Record<string, React.ComponentType<FormatterProps>>; // 按需导入组件并创建映射(比import *更清晰可控) import StringFormatter from './StringFormatter'; import NumberFormatter from './NumberFormatter'; // 导入其他Formatter组件... const formatterMap: FormatterMap = { StringFormatter, NumberFormatter, // 注册其他组件... }; // 简化类型守卫函数 function isFormatterKey(key: string): key is keyof typeof formatterMap { return key in formatterMap; }
2. 优化动态组件获取逻辑
function getFormatter(type: string, name: string, meta: JsonApiMetaAttributeType): React.ComponentType<FormatterProps> { const formatterName = `${capitalizeFirstLetter(meta[type][name].type)}Formatter`; // 直接返回目标组件或默认组件,避免额外变量赋值 return formatterMap[formatterName as keyof typeof formatterMap] || formatterMap.StringFormatter; }
3. 简化渲染逻辑
使用Object.entries替代Object.keys,直接获取属性名与值,代码更简洁:
{ Object.entries(item.attributes).map(([attrName, attrValue]) => { const FormatterComponent = getFormatter(item.type, attrName, meta); return ( <td key={`data-cell-${attrName}`}> <FormatterComponent> {attrValue} </FormatterComponent> </td> ); }) }
4. 额外优化建议
- 若不同组件有差异化props,可通过
React.ComponentType泛型或联合类型适配 - 将默认组件设为可配置项,避免硬编码
StringFormatter - 对
meta[type][name].type添加空值检查,防止访问不存在的属性引发报错
内容的提问来源于stack exchange,提问作者Maksym Tymofeiev
相关产品推荐
相关产品推荐

