Rendering a built-in element or a custom component dynamically
In JSX, React distinguishes between:
- built-in HTML elements: lowercase names like
div,button,section - custom components: capitalized names like
Card,Button,Profile
A common pattern is to pass the element/component as a prop and render it dynamically.
type BoxProps = {
as?: React.ElementType;
children: React.ReactNode;
};
function Box({ as: Component = 'div', children }: BoxProps) {
return <Component>{children}</Component>;
}
export default function App() {
return (
<>
<Box as="section">This is a section</Box>
<Box as={CustomCard}>This uses a custom component</Box>
</>
);
}
function CustomCard({ children }: { children: React.ReactNode }) {
return <div style={{ border: '1px solid #ccc', padding: 12 }}>{children}</div>;
}
Important rules:
-
as="section"renders a built-in HTML tag. -
as={CustomCard}renders a custom React component. - The component name must start with an uppercase letter.
-
asis just a prop name here; React does not give it special meaning by itself.
A simpler version is also valid:
function Button({ Tag = 'button', children, ...props }) {
return <Tag {...props}>{children}</Tag>;
}
Then:
<Button Tag="a" href="#">Link</Button>
<Button Tag={PrimaryButton}>Custom button</Button>
Top comments (0)