EN
React / JSX - how to define functional component that accepts children with same attributes / props only?
1
answers
2
points
I am working on some project where I need to create custom floating properties component.
Main idea is to create component that allows to put properties components as children.
I would like to allow to use different child components that accept same props.
Expected example usage:
<FloatingProperties>
<FloatingTextProperty title="User name" value="John Doe" /> {/* text type */}
<FloatingTextProperty title="User age" value="25" /> {/* text type */}
<FloatingDateProperty title="Creation date" value="2020-07-01" /> {/* date type */}
<Text title="Creation date" value="2020-07-01" /> {/* not allowed - not property component */}
</FloatingProperties>
I know how to do it with one child type:
// I use rebass library
type FloatingTextPropertyProps = {
title: string;
value: string;
};
const FloatingTextProperty = ({title, value} : FloatingTextPropertyProps) => {
reutrn (
<Box variant="floatingProperty">
<Box variant="propertyTitle">{title}</Box>
<Box variant="propertyValue">{value}</Box>
</Box>
);
};
type FloatingPropertiesProps = {
children: FloatingTextProperty[]; // maybe, should I use some inheritance here?
};
type FloatingProperties = ({children} : FloatingPropertiesProps) => {
reutrn (
<Flex variant="floatingProperties">
{children}
</Flex>
);
};
Is It possible to do it?
1 answer
1
points
Try to use ReactElement<MyProps, FunctionComponent<MyProps>>
as type of children with your component.
Full example below:
import React, { ReactNode, FunctionComponent, ReactElement } from 'react';
import { Flex, Text } from 'rebass';
type MyProps = {
title: string;
value: ReactNode | string | number | boolean | null;
};
const MyValue = ({ title, value }: MyProps) => {
return <Text title={title}>{value}</Text>;
};
const MyBoolean = ({ title, value}: MyProps) => {
const text = title === 'true' ? 'Yes' : 'No';
return <Text title={text}>{text}</Text>;
};
type MyChild = ReactElement<MyProps, FunctionComponent<MyProps>> | null;
type MyGroupProps = {
children?: MyChild | MyChild[];
};
const MyGroup = ({ children }: MyGroupProps) => {
return <Flex>{children}</Flex>;
};
const App = () => {
return (
<MyGroup>
<MyValue title="Name" value="Kate" />
<MyValue title="Occupation" value="Front-end developer" />
<MyBoolean title="Active" value="true" />
</MyGroup>
);
};
Solution:
MyBoolean
and MyValue
components use the same props (MyProps
). Later MyGroup
uses as children components that uses MyProps
defined by MyChild | MyChild[]
- we allow for 0, 1, 2, 3, etc. children.
0 comments
Add comment