Hello,
I’m working on migrate my portfolio from JS to TS and i got the next problem:
I have a model with a dynamic zone(we used Strapi-to-Typescript to get them) as follows:
export interface IPage {
id: string;
title?: string;
slug: string;
thumbnail?: IFile;
body: (
| ({ __component: "content.rich-text" } & IRichText)
| ({ __component: "content.experience" } & IExperience)
| ({ __component: "content.personal-information" } & IPersonalInformation)
| ({ __component: "fields.skill" } & ISkill)
)[]; // IComponent[]
tags?: ITag[];
description?: string;
}
I have a component how renderizes this body:
export const Body = ({ body }) => {
return body.map((component) => (
<DynamicZone key={`component${component.id}`} component={component} />
));
};
And the dynamic zone component is:
export const DynamicZone = ({ component, className }) => {
const classes = useStyles();
const { i18n } = useTranslation();
return (
<Typography
variant="body1"
component="section"
className={clsx(classes.root, className)}
>
{
{
ComponentContentContent: (
<Content>
component
</Content>
),
ComponentFieldsSkill: <Skill {...component} />,
}[component.__typename]
}
</Typography>
);
};
It is like that since the normal GraphQL json response comes like:
"body": [
{
"__typename": "ComponentContentPersonalInformation",
"id": "2",
"name": "José Luis Sandoval Alaguna",
"photo": {
"alternativeText": "Profile photo.",
"caption": "José Luis Sandoval Alaguna",
"url": "https://res.cloudinary.com/dqhx2k8cf/image/upload/v1608399687/fotodeperfil_029e62c5d9.jpg",
"width": 970,
"height": 1296
},
"position": "Front-End Developer at CloudNesil",
"nationality": "Colombian",
"address": {
"address": "6438 Sokak. Yunusemre Mah. No: 5 Daire: 1, Pamukkale",
"city": "Denizli",
"country": "Turkey",
"postalCode": null
},
"telephone": [
{
"id": "1",
"type": "Mobile",
"number": 5373749236
}
],
"mail": "alagunasalahaddin@live.com",
"links": [
{
"id": "1",
"type": "LinkedIn",
"url": "www.linkedin.com/in/jluissalaguna/"
},
{
"id": "2",
"type": "Github",
"url": "www.github.com/SalahAdDin"
},
{
"id": "3",
"type": "StackOverflow",
"url": "stackoverflow.com/users/3826549/salahaddin"
}
],
"aboutMe": null
},
{
"__typename": "ComponentFieldsSkill",
"type": "Language",
"id": "6",
"name": "Español (Native)",
"level": 5
},
So, migrating the dymanic zone we have:
type IComponent =
| ({
__component: "content.rich-text";
__typename: "ComponentContentRichText";
} & IRichText)
| ({
__component: "content.experience";
__typename: "ComponentContentExperience";
} & IExperience)
| ({
__component: "content.personal-information";
__typename: "ComponentContentPersonalInformation";
} & IPersonalInformation)
| ({
__component: "fields.skill";
__typename: "ComponentFieldsSkill";
} & ISkill);
interface IDynamicZone {
component: IComponent;
className?: string;
}
const DynamicZone: React.FC<IDynamicZone> = ({ component, className }) => {
const classes = useStyles();
return (
<Typography
variant="body1"
component="section"
className={clsx(classes.dynamicZone, className)}
>
{
{
ComponentContentContent: <Content>{component}</Content>,
ComponentFieldsSkill: <Skill {...component} />,
}[component.__typename]
}
</Typography>
);
};
But, we are getting the next problems:
What’s the best way to handle a dynamic zone component?
Thanks