I'll explain one of the best way (in my opinion) to keep your React components
clean and reusable. I'll be using TypeScript for this and we'll start with
a simple Button
component:
type Props = {
children: string
}
function Button({ children }: Props): JSX.Element {
return (
<button>
{children}
</button>
)
}
export default Button
Now we want to add a property to this button called size
, that's as easy as:
type Props = {
children: string
size?: string
}
function Button({ children, size }: Props): JSX.Element {
// ...
If you're wondering why
size?
has a?
andchildren
doesn't, it means thatsize
is an optional property.
Alright, to use this component we can do:
<Button size="md">
Buy now!
</Button>
That's totally fine and it should work just fine. Although I'm assuming
we'll be using this component a lot through our app. Plus, the value of size
that we can pass through it'll not be just md
right?
This starts to get a little confusing once you start using Button
over and
over again.
Enums
One way of dealing with the available sizes for our button is by using enums
, lets
assume our button can have the following sizes: sm
, md
, lg
and xl
.
In our Button
component we can create an enum
to list those:
enum Sizes {
SM = 'sm',
MD = 'md',
LG = 'lg',
XL = 'xl',
}
type Props = {
children: string
// We can also say that from now on the property
// `size` needs to be one of `Sizes`
size?: Sizes
}
function Button({ children, size }: Props): JSX.Element {
// ...
What's good about using an enum
? We can export it so it can be used all
across your application:
export enum Sizes {
SM = 'sm',
MD = 'md',
LG = 'lg',
XL = 'xl',
}
When importing and using our button we would do this:
import Button, { Sizes } from '@components/Button'
// ...
<Button size={Sizes.MD}>
Buy now!
</Button>
So, if for some reason the value of Sizes.[SM | MD | LG | XL]
changes you
only need to care about changing the logic in your Button
component, not on
every iteration of Button
across the application. This of course can be used for whatever prop you feel it makes sense to use enums
.
Another example can be the button type
:
export enum Types {
PRIMARY = 'primary',
SECONDARY = 'secondary',
DANGER = 'danger',
}
And using it:
import Button, { Sizes, Types } from '@components/Button'
// ...
<Button type={Types.PRIMARY} size={Sizes.MD}>
Buy now!
</Button>
That's it. Follow me on Twitter โ๐ป