在开发复杂的React应用时,我们经常遇到后端返回的数据结构不一致的情况。这可能会导致前端处理逻辑变得复杂,特别是当我们需要将这些数据用于UI组件,如下拉选择框时。本文通过一个具体示例,探讨如何使用TypeScript和React来灵活处理这种多样化的数据结构,确保组件的可重用性和类型安全。
定义不同的数据结构接口考虑到后端可能返回不同结构的数据,我们首先定义了两种接口来描述这些可能的数据结构:
export interface CodeListItems { cd: string; cdNm: string;}export interface CodeListItems2 { value: string; label: string;}这两种接口分别代表了两种不同的数据项格式。CodeListItems 适用于后端返回的数据项包含 cd 和 cdNm 的情况,而 CodeListItems2 则适用于数据项包含 value 和 label 的情况。
使用类型断言处理数据结构转换在React组件中处理这些不同的数据结构时,我们可以使用TypeScript的类型断言(as)来转换数据类型,从而允许组件处理不同形式的数据:
type OptionCodeList = { [key: string]: string }export interface CmCdNameTextProps<T = CodeListItems[] | OptionCodeList[]> extends TextProps { code: ConstantCode.GET_CODE_KEY | T, cd: string, label?: string, labelNm?: string,}在上述代码中,CmCdNameTextProps 接口通过泛型 T 允许传入 CodeListItems[] 或 OptionCodeList[] 类型的数据,其中 OptionCodeList 是一个键值对映射,用于更通用的情况。
实现组件逻辑接下来,我们实现了一个名为 CmCdNameText 的React组件,它根据传入的 code、cd、label 和 labelNm 属性来显示对应的文本信息:
function CmCdNameText<T = CodeListItems[] | OptionCodeList[]> (props: CmCdNameTextProps<T>) { const { code, cd, label, labelNm, ...restProps } = props const [items, setItems] = useState<T>(() => code as T) const [cdNm, setCdNm] = useState('') useEffect(() => { let name = '' if (label && labelNm) { name = CmUtils.getDicCdName(cd, items as unknown as OptionCodeList[], { cd: label, cdNm: labelNm, }) } else { name = CmUtils.getDicCdName(cd, items as unknown as ConstantCode.CodeListItems[], { cd: 'cd', cdNm: 'cdNm', }) } setCdNm(name) }, [cd, label, labelNm, items]) return <Text {...restProps}>{cdNm}</Text>}在这个组件中,我们使用了React的 useState 和 useEffect 钩子。通过类型断言,我们将 code 属性断言为 T 类型,并基于 label 和 labelNm 的存在来选择不同的处理逻辑。这种方式使我们能够根据不同的数据结构获取相应的显示名称。
总结这个示例展示了如何在React和TypeScript环境中,灵活处理后端返回的不同数据结构。通过定义清晰的接口和利用类型断言,我们可以在组件中灵活处理多种数据格式,同时保持代码的可读性和类型安全。这种方法对于提高前端应用的灵活性和可维护性非常有帮助,特别是在与后端服务交互频繁的现代Web应用开发中。
如果喜欢,可以点赞收藏,关注哟~