TL;DR
Polymorphic component is a React component that has ability to use other HTML element as the returned element.
// Example of polymorphic component
<Button as="a" href="...">
About
</Button>
With this approach, it gives you a control to customize the returned element from a component.
This is one of UI component that implement polymorphic component.
mantinedev / mantine
A fully featured React components library
Mantine
Links
Packages
-
@mantine/hooks
– collection of 50+ hooks for state and UI management -
@mantine/core
– core components library – 100+ components -
@mantine/form
– forms management library -
@mantine/charts
– recharts based charts library -
@mantine/notifications
– a fully featured notifications system -
@mantine/spotlight
–Ctrl + K
command center for your application -
@mantine/code-highlight
– code highlight built with highlight.js -
@mantine/tiptap
– a Tiptap based rich text editor -
@mantine/dropzone
– manages files drag 'n' drop to an area or entire screen -
@mantine/carousel
– Carousel component -
@mantine/nprogress
– navigation progress -
@mantine/modals
– centralized modals manager
Getting help
Mantine has a very friendly community, we are always happy to help you get started:
- Join Discord community – it is the easiest way to get help, all questions are usually answered in about 30 minutes
- GitHub Discussions – ask anything about the…
Introduction
When building user interface, we often facing an issue where a component not flexible enough.
Let's say you have a component like this.
function Button({ children, ...props }) {
return <button {...props}>{children}</button>;
}
You can use component above to create a beautiful button. Nothing wrong with that component. Until someday you want create a link with same style with the <button />
component.
Maybe you will use this approach.
<a href="...">
<Button>To next page</Button>
</a>
Of course it should work, but the code doesn't look so fluent. Meaning to say. If you use HTML, you can write it like this:
// We assume <a /> using same styling with <button />
<a href="...">To next page</a>
Based on the problem above, polymorphic component offers you a solution like this:
<Button as="a" href="...">To next page</a>
See? You don't need to wrap the <Button />
component using <a />
because it's automatically convert the the returned element to <a />
.
Building The Component
Now let's build the component and it's very easy. All you need is only React createElement
API.
💡NOTE:
Read thecreateElement
API documentation for more information.
We have this component from the previous section.
function Button({ children, ...props }) {
return <button {...props}>{children}</button>;
}
From this normal component, we will refactor it to polymorphic component.
function Button({ children, as, ...props }) {
return React.createElement(as || 'button', props, children);
}
Let me explain the code above.
- function Button({ children, ...props }) {
+ function Button({ children, as, ...props }) {
return React.createElement(as || 'button', props, children);
}
Here we added as
props. This props holds a value of what element will returned.
It's not a must to name it as
. Some UI library name it element
, component
, or whatever you like.
function Button({ children, as, ...props }) {
- return <button {...props}>{children}</button>;
+ return React.createElement(as || 'button', props, children);
}
We also changed the JSX to createElement
API to give us more control when creating the component.
If you not familiar. Actually when you use JSX, under the hood it will transform your code to createElement
.
By using the createElement
API, we are able to conditionally create a component. That's why when you are not passing a value into the as
props, the default element of <Button />
component is <buttton />
.
And that's it... You have created a polymorphic component.
Conclusion
Polymorphic component may sounds very fancy and difficult, but it's not.
The term of polymorphic is a general term in computer science. You can read about it here.
One of my favorite backend framework, Laravel, is also has a feature called polymorphic relationships which use this term.
In React world, polymorphic component refers to an ability of a component that can returns different element with a same style without removing the default functionality.
It's really help when you facing a problem where you want to use other HTML with a same style.
I hope it gives you something. Thanks for reading :)
Top comments (0)