React patterns: How to create a wrapper around a native HTML element
13 November 2022 (Updated 2 August 2024)
Suppose you want to create a component that is a wrapper around an existing HTML element like the <button>
element.
For example, you might want to create a <ToolbarButton>
the component that acts exactly like a button but has specific classes applied depending on whether it’s in an active state or not.
Here’s an approach you can take (example):
import React, { ButtonHTMLAttributes } from 'react'
import classNames from 'classnames'
type Props = React.ButtonHTMLAttributes<HTMLButtonElement> & {
isActive?: boolean
}
const ToolbarButton: React.FC<Props> = ({
className,
isActive = false,
...props
}) => {
const defaultClasses = 'border px-2 py-1 border-black mr-3'
return (
<button
// This is the essential step. You want to spread all the
// props to the button.
{...props}
className={classNames(
{ 'bg-black text-white': isActive },
defaultClasses,
className
)}
/>
)
}
export default ToolbarButton
A simpler example:
import classNames from 'classnames'
import React from 'react'
type Props = React.HTMLAttributes<HTMLHeadingElement>
const FormGroup: React.FC<Props> = ({ className, ...rest }) => (
<div className={classNames('mb-2', className)} {...rest} />
)
export default FormGroup
Tagged:
React patterns
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment