首页 > 解决方案 > 带有道具的动态组件名称反应

问题描述

我有一个PropertyCardList接受一些props. 我只想从父级传递组件名称,列表应该自动呈现它。

PropertyCardList.tsx

import React from "react";
import { Grid, GridProps, GridSpacing } from "@material-ui/core";
import { NamedExoticComponent } from "react";
import { LargePropertyInfo, SmallPropertyInfo } from "../../@types/Property/Property";
import { SmallPropertyCardProps } from "../PropertyCards/SmallPropertyCard/SmallPropertyCard";
import { LargePropertyCardProps } from "../PropertyCards/LargePropertyCard/LargePropertyCard";

interface Props
{
    gridSpacing?: GridSpacing;
    gridItemProps?: GridProps;
    loading?: boolean;
    skeletonsCount?: number;
    properties: SmallPropertyInfo[] | LargePropertyInfo[];
    cardComponent: NamedExoticComponent <SmallPropertyCardProps> | NamedExoticComponent <LargePropertyCardProps>;
}

const PropertyCardList: React.FC <Props> = props =>
{
    if (props.loading)
    {
        return (
            <Grid container spacing={props.gridSpacing}>
                {new Array(props.skeletonsCount).fill(null).map((_, index) => (
                    <Grid
                        item
                        key={index}
                        {...props.gridItemProps}
                    >
                        <props.cardComponent
                            property={{}} // I have to typecast it using "as" but what should be the value?
                            loading={true}
                        />
                    </Grid>
                ))}
            </Grid>
        )
    }

    return (
        <Grid container spacing={props.gridSpacing}>
            {props.properties.map((property) => (
                <Grid
                    item
                    key={property.id}
                    {...props.gridItemProps}
                >
                    <props.cardComponent
                        property={property} // I get error here saying that subType, ownership missing in SmallPropertyInfo. It makes sense but this needs to be dynamic as well
                    />
                </Grid>
            ))}
        </Grid>
    );
}

PropertyCardList.defaultProps = {
    skeletonsCount: 3,
}

export default React.memo(PropertyCardList);

接口

export interface PropertyBase
{
    id: string;
    images: string[];
    beds: number;
    baths: number;
    areaSize: number;
    price: PropertyPrice;
    address: ObjectWithTranslation;
}

export interface SmallPropertyInfo extends PropertyBase
{
    purpose: PropertyPurpose;
}

export interface LargePropertyInfo extends SmallPropertyInfo
{
    subType: PropertySubType;
    ownership: PropertyOwnership;
    installment: Omit <PropertyPrice, "type">;
}

以下是我使用列表组件的方式:

<PropertyCardList
    cardComponent={isMobile ? SmallPropertyCard : LargePropertyCard}
    properties={properties.data}
    gridSpacing={2}
    gridItemProps={{
        lg: 6,
        xs: 12
    }}
    loading={loading}
    skeletonsCount={5}
/>

这是使列表组件通用的正确方法还是应该为每种类型制作单独的列表组件?(这会重复很多代码)

标签: reactjstypescript

解决方案


可以在 react 中使用条件渲染,这对删除冗余编码实现非常有帮助。

您可以将其作为函数体中的变量,如下所示。

const cardComponent= isMobile ? SmallPropertyCard : LargePropertyCard

然后使用它传递给子组件,如下所示。

<PropertyCardList
    cardComponent={cardComponent}
    properties={properties.data}
    gridSpacing={2}
    gridItemProps={{
        lg: 6,
        xs: 12
    }}
    loading={loading}
    skeletonsCount={5}
/>

你使用它的方式也是正确的。


推荐阅读