DEV Community

Sarah Katz
Sarah Katz

Posted on

Props Are Not Forever: Preventing Props From Being Passed to the DOM with styled-components v5.1

At work, my team uses styled-components as our CSS-in-JS solution. I've enjoyed working with styled-components and have found it to be a very powerful solution for our needs, but one issue I've encountered a few times is needing to pass props to a styled component for conditional styling and then having those props show up on the DOM and lead to a console error. I recently discovered (thanks to a teammate's comment on a PR I was reviewing) two new functionalities added to styled-components v5.1.0 that I think will reduce these errors in the future, and today I'd like to give a brief overview of this new functionality and how I plan to use it.

shouldForwardProp

shouldForwardProp is a config option that determines if a given prop should be forwarded to the DOM. For example, you may want to pass "height" and "width" properties to the DOM, but if you have a property called shouldBePurple that determines whether or not the styled component has a purple background, that likely does not need to be passed to the DOM.

shouldForwardProp accepts a prop and optionally the defaultValidatorFn, a function that is used by styled-components as the default function to determine if a prop should be passed.

const Include = styled('div').withConfig({ 
  shouldForwardProp: (prop, defaultValidatorFn) =>  
    ['height','width'].includes(prop)
})`
 height: props.height;
 width: props.width;
 color: props.deeppink;
`

<Include height="16px" width="24px" color="deeppink" />

# Renders: <div height="16px" width="24px" />
Enter fullscreen mode Exit fullscreen mode

This can also be used to specify props to not include:

const Exclude = styled('div').withConfig({ 
  shouldForwardProp: (prop, defaultValidatorFn) => 
    !['color','banana'].includes(prop)
})

<Exclude height="16px" width="24px" color="deeppink" />

# Renders: <div class="whatever" height="16px" width="24px" />
Enter fullscreen mode Exit fullscreen mode

There are a lot of areas in my team's codebase where I could see the use of this new config option. One area in particular where it could be helpful, and where I'd like to have an opportunity to apply it, is in our design system. We have a number of components in our design system that receive props used exclusively for styling, and I'm hoping to get a chance to take a deeper look at these components and see if we can use the shouldForwardProp config to minimize the props we pass through to the DOM.

transient props

Transient props are props that don't get passed to the DOM. Similar to shouldForwardProp, this is a way for styled-components to know that a prop is only used for styling and should not make its way to the DOM.

Transient props achieve the same end as shouldForwardProp, and often the two can be used interchangeably, but there are situations where one may be more useful than the other. Personally, I feel that transient props are more useful when there are many props to filter out and listing those props in shouldForwardProp could create unnecessary confusion or extra code.

Transient props start with the $ symbol.

const Paragraph = styled.p`
  padding-bottom: ${props => !!props.$bottomPad ? '24px' : '0px'};
`;

<Paragraph $bottomPad={true}>I Have Bottom Padding</Paragraph>;
# Renders: 
<p style="padding-bottom: 24px">I Have Bottom Padding</p>;

<Paragraph>I Have No Bottom Padding</Paragraph>;
# Renders: 
<p>I Have No Bottom Padding</p>;

Enter fullscreen mode Exit fullscreen mode

We've already started using transient props in my company's codebase (see PR mentioned above), and I have one specific use in mind. As part of a recent project, I introduced a prop that is used for styling, but I have since noticed that this prop is creating a console error on the DOM (oops). I'm hoping that I get a chance soon to replace this prop with a transient prop and fix that DOM error.

Most of the libraries and frameworks that are commonly used add new functionalities from time to time. It can be hard to keep up with these new functionalities (I'm pretty bad at it - probably would not have discovered these new styled-components functionalities without a teammate explicitly calling them out), but if you're running into a problem with a particular library, it may be worth looking to see if it has introduced new functionality that can help. As someone whose company uses styled-components fairly heavily, I'm excited to have discovered shouldForwardProp and transient props, and I know I will be using them in my future development work.

Top comments (2)

Collapse
 
room_js profile image
JavaScript Room

Thank you, Sarah! That's a great dive into this topic! I wanted to share another (simplier) way of achieving this, just learned it myself: name your prop starting from $ and then the styled component automatically does this magic for you. So withConfig() is not needed in that case.

Collapse
 
sagit profile image
Sagi Janos

Thank you Sara! You save my day :D Great article