Intro
When building a component library, one of the most important things is a seamless and clean documentation of the available properties of a component.
Users of your component library should not be able to write random properties on components which are not used by it. Otherwise an error like Warning: React does not recognize the 'isVisible' prop on a DOM element. [...] If you accidentally passed it from a parent component, remove it from the DOM element.
can be thrown quickly.
The data-* and why we sometimes need it
There are use cases in which users need to have the ability to pass some kind of random properties on the components.
For me, such a use case was adding selector attributes for End-2-End tests like data-test-element="header"
to the libraries components in my project.
(BTW: I love to write my E2E tests with cypress.)
Solution
A small and simple function which takes your property object and returns just valid properties that should appear in the rendered markup.
const validateProps = (props) => {
const newProps = {}
Object.keys(props).forEach((key) => {
if (key.startsWith('data-') || key === 'className') newProps[key] = props[key]
})
return newProps
}
Usage
In your components you can extract the properties which are used by it self. All other properties are passed through validateProps()
.
const Badge = ({ onToggle, isActive, children, ...props }) => (
<Wrapper
isActive={isActive}
onClick={onToggle}
{...validateProps(props)}
>
{children}
</Wrapper>
)
??? className ???
Maybe you wonder why validateProps()
keeps the className
property? That's because I work with styled-components. If you add some custom styling from outside to a component you will have to write this property on the component (see styled-component docs)
Prod vs. Dev
Depending on how and where you run your tests, you maybe don't want to see those data-test-*
attributes in your markup in production.
In this case I recommend babel-plugin-react-remove-properties.
Usage
Filter all data-test-element
properties only in production with the following config in the .babelrc
of your project.
{
"env": {
"production": {
"plugins": [
[
"react-remove-properties", {
"properties": [
"data-test-element"
]
}
]
]
},
}
}
Top comments (0)