DEV Community

Atilla Baspinar
Atilla Baspinar

Posted on

React: Dynamic rendering

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>;
}
Enter fullscreen mode Exit fullscreen mode

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.
  • as is 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>;
}
Enter fullscreen mode Exit fullscreen mode

Then:

<Button Tag="a" href="#">Link</Button>
<Button Tag={PrimaryButton}>Custom button</Button>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)