Polymorphism with withComponent
ThewithComponent function allows you to create a new component that renders a different element or component while preserving the original component’s styles. This is a build-time alternative to the runtime as prop pattern.
Basic Usage
HTML Elements
Create a component that renders a different HTML element:React Components
UsewithComponent with any React component that accepts a className prop:
How It Works
At build time, the Vite plugin transformswithComponent calls into optimized component factories:
Key Features
- Zero Runtime Overhead: Component creation happens at build time
- Type Safety: Full TypeScript inference for component props
- Style Preservation: Inherits all styles from the source component
- Composable: Can be extended further with
styled() - className Support: User-provided
classNameprops are merged correctly
Advanced Patterns
Extending Polymorphic Components
You can extend polymorphic components with additional styles:Multiple Polymorphic Variants
Create multiple variants of the same component for different use cases:Conditional Polymorphism
Choose components dynamically based on props:Type Safety
The resulting component is fully type-safe and inherits all props from the target component:Comparison with Runtime as Prop
Many styled-component libraries use a runtime as prop for polymorphism:
withComponent for build-time polymorphism instead:
| Feature | Runtime as | Build-time withComponent |
|---|---|---|
| Performance | Runtime overhead | Zero runtime cost |
| Type Safety | Often loses type inference | Full type safety |
| Bundle Size | Included in bundle | Tree-shakeable |
| Flexibility | Change at runtime | Defined at build time |
| API | Prop-based | Function-based |
Best Practices
1. Create Semantic Variants
Name polymorphic components based on their semantic purpose:2. Colocate Related Variants
Keep polymorphic variants near their base component:3. Document Prop Requirements
Clearly document which props are needed for each variant:4. Limit Polymorphic Depth
Avoid deeply nested polymorphic compositions:Troubleshooting
Component Not Receiving Styles
Ensure the target component accepts and applies aclassName prop:
Type Errors with Custom Components
Make sure your component is properly typed with React.ComponentType:Related
- Configuration - Configure the Vite plugin
- TypeScript - Type safety and inference
- styled API - Using
.classNamefor manual composition