Many modern projects leverage UI libraries to speed up development time with some popular choices are Material-UI and Chakra UI. What many developers will do is simply import the UI element they want, style it the way they want and just use it where they need. This works well enough but what quickly becomes a problem is if you need to add multiple of the same element with similar styling and functionality. You may end up copying and pasting code all over which becomes a pain to maintain when you want to change anything.
So what do you do? Add the element to its own component and add a wrapper around components from UI libraries.
A good example is say you want to import a button from Chakra UI but you don’t like the default colors for the button or maybe you want to add an animation. Instead of importing it directly where you want it and just adding the modifications you want, you create a component on its own and import it there, make the modifications and export the new component to be used throughout your project.
Wrapped element
import React from "react";
import { Button as ChakraButtonComponent } from "@chakra-ui/react";
interface ButtonProps extends React.ComponentProps<typeof ChakraButtonComponent> {
//Add additional prop definitions here
mySpecificProp: string;
}
const Button = (props: ButtonProps) => {
return (
<ChakraButtonComponent className="button-class" {...props}>
{props.children + " " + props.mySpecificProp}
</ChakraButtonComponent>
);
};
export default Button;
Wrapped element in use
import Button from "./button";
const MyComponent = () => {
return (
<div>
<Button mySpecificProp="hello">My Button!</Button>
</div>
);
};
export default MyComponent;
In the above example, we import our UI element from our UI library (renaming it to something descriptive but this is not necessary). We then declare the interface for the component props of the component we intend to export. The most important line here is … extends React.ComponentProps. What this will do is give you the intellisense for the props of the UI element without having to explicitly declare them. We can also add additional props as well, like if we have a specific use case for this element and it needs to take props for that. The last thing here is to return the element from the UI element and spread the props using the spread operator in the element.
There are several benefits to doing this:
Whenever you want a button element, you import this element instead of the element from the UI library directly. If you ever need to make a sweeping change to all your buttons in your app, you only change this component as opposed to every instance of the button.
You can apply all the use case specific things you need for this particular element.
You aren’t as locked in to your UI library. Say, for instance, you decide that Chakra UI is no longer serving your needs or there’s another UI library you want to experiment with. Changing to another UI library is as easy as simply changing the import and potentially renaming elements in the file. The props will obviously change as it’s a different element so that might need to be updated throughout your application but other than that, that’s it.
Thanks so much for reading and I hope you found this article interesting and helpful! Feel free to leave a like on this article if you liked it or a comment if you have any questions!
If you’d like to learn more about Front-End Development, follow me here on Dev.to, on Twitter and LinkedIn. Also check out hot.opensauced.pizza to see the hottest open source repositories!