Understanding Transient Props in styled‑components

Hero image for Understanding Transient Props in styled‑components. Image by Inspirationfeed.
Hero image for 'Understanding Transient Props in styled‑components.' Image by Inspirationfeed.

This is an interesting one for me. At the moment, I'm working on a replatforming project for my airline client where my team and I are moving a monolithic legacy application from a combination of React, Handlebars and Java (using Emotion) to an allnew headless, Next.js application using GraphQL and styledcomponents.

Because much of the existing application is already built in React, a lot of current work involves what our product owner would refer to (oversimplistically) as 'lift and shift' work, where a component gets copied from one project to another and minimally reworked in order to make it compatible with the new environment.

Last week, one of my team came to me with an interesting warning cropping up in their browser console:

A screenshot from Google Chrome's console showing a styled-components transient props warning: 'styled-components: it looks like an unknown prop "truncated" is being sent through to the DOM, which will likely trigger a React console error. If you would like automatic filtering of unknown props, you can opt into that behaviour via `<StyleSheetManager shouldForwardProp={...}>` (connect an API like `@emotion/is-prop-valid`) or consider using transient props (`$` prefix for automatic filtering.)'.

To offer a little context, they were working on a panel which truncates text based on a boolean state item, and although it's only a warning and seemingly was having no ill effects in the wider application, it was something that they didn't want going into production code (and which I agree with).

This was a problem with the props being passed into the styled component and something that styledcomponent's transient props would solve.


What are/is styledcomponents?

Let's start at the beginning. styledcomponents is a library which allows us as developers to write CSS directly within our JavaScript (specifically: in React and React Native applications). It uses tagged template literals as a means to define styles at the componentlevel. This results in a really modular architecture which makes management and maintenance more straightforward across larger codebases.

The biggest advantages are that the styling is scoped within the component (so no leaky styling), and as we're discussing allows us to dynamically update the styling of a component based on state or props.

Props in styledcomponents

This is where styledcomponents is interesting (I think). You can pass props to a styled component just like you would any other React component. I won't go into too much detail, but to offer a brief example, here's the style declaration for an accordiontype drawer:

export const AccordionDrawer = styled.div<{ open: boolean }>`  display: block;  max-height: ${({ open }) => (open ? '100rem' : '0')};  overflow: hidden;  transition: max-height 0.3s ease-in-out;`;

The prop open is a boolean. When it is true, the maxheight of the div will be 100rem, when it is false, it will be 0. We then use it like this, setting open in the parent component's state object, and putting whatever content we like within it:

<AccordionDrawer open={open}>  <p>Lorem ipsum dollar</p></AccordionDrawer>

Pretty cool, right?


The Need for Transient Props

The gotcha in this use of props is that when you pass a prop to a styled component, these props are also passed down to the underlying DOM element (in the example above: the div which makes up AccordionDrawer). As you might imagine, since open is not a valid attribute of a div (or HTMLDivElement), this then causes a warning from React in the browser console like "Unknown prop" or "Received true for a nonboolean attribute.", which in turn could potentially lead to performance issues.

To address this, styledcomponents introduced transient props.


What are Transient Props?

Transient props are quite simply props which have been prefixed with a dollar sign ($). styledcomponents uses this prefix to avoid forwarding the prop to the DOM element beneath. These were introduced in v5.1.0 of styledcomponents, since May 2020. This enhances our prop management by preventing nonstandard attributes from cluttering the DOM.


Using Transient Props

Using transient props is quite literally as simple as prepending the dollar sign to your prop names. Going back to our earlier example, it would now look like this:

export const AccordionDrawer = styled.div<{ $open: boolean }>`  display: block;  max-height: ${({ $open }) => ($open ? '1000px' : '0')};  overflow: hidden;  transition: max-height 0.3s ease-in-out;`;

The difference is subtle. In use it would now look like this:

<AccordionDrawer $open={open}>  <p>Lorem ipsum dollar</p></AccordionDrawer>

As you can see, all we've done here is change the open prop to $open. That dollar sign is all that is needed to signal to styledcomponents that this is a prop that we only want to use in the styling of the component, and not pass further down to the DOM itself.


Wrapping up

So, all that we needed to do to resolve my developer's console warnings was to add a $ to that prop names. By preventing nonstandard props from being passed into the DOM, transient props can help us reduce warning clutter in the console, markup clutter in the DOM, and maybe just improve performance just that little bit more.

For more details, you can check the styledcomponents release notes, the GitHub discussion on transient props, and the original discussion about workarounds from when this issue first arose.


Categories:

  1. CSS
  2. Development
  3. Front‑End Development
  4. React
  5. styled‑components