Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do I use attrs vs passing props directly with styled-components?

I am a bit confused as to when I should use the attrs constructor to pass props in styled-components:

const Example = styled.div.attrs(props => ({
  style: {
    color: props.color
  }
}))``;

and when I should just pass them direcly:

const Example = styled.div`
    color: ${props => props.color}
`

I understand that the first method is changing the in-line style and the second is generating a class but I'm unsure of the implications of these differences.

I have seen an error in the console that says "Over 200 classes were generated for component styled.div. Consider using the attrs method, together with a style object for frequently changed styles."

But at the same time it says in the docs "The rule of thumb is to use attrs when you want every instance of a styled component to have that prop, and pass props directly when every instance needs a different one."

Why not just use one of these methods all the time? When should I use each one and why?

like image 970
Wilson Avatar asked Feb 05 '20 16:02

Wilson


1 Answers

(TL;DR at the end)

The problem is that you're reading about two separate use-cases, and assuming that they are explaining the same thing.

The Styled Components .attrs method is for passing props to a styled component. When the docs say that you should use .attrs "when you want every instance of a styled component to have that prop", they mean something like this:

const CheckboxInput = styled.input.attrs({ type: "checkbox" })`
   margin: 10px;
`;

This means that when you use <CheckboxInput />, it will be a checkbox by default, no need to define the prop type="checkbox" every time. This is the main purpose of the .attrs method.

So you understand that when you add style to that component's attrs, it's exactly the same as passing style as a prop to a regular, non-styled component. It just adds that style as an inline style, skipping any optimisation that styled-components might make. Inline styles aren't usually recommended because they will always be attached as an individual style to every version of that component. Example:

// items is some array with 100 elements
items.map(item => (
  <button style={{ background: 'blue' }} >{item.text}</button>
));

This would generate 100 buttons, and each button would have their own instance of the background: blue style.

With Styled Components, you would do this:

const button = styled.button`
   background: blue;
`;

This would generate the style only once, no matter how many buttons you have. Because it actually generates a CSS class.

Unfortunately, generating CSS classes isn't a lightweight operation, so if for instance you're doing animations or doing anything that changes a style frequently, it's recommended to go with inline styles instead.

TL;DR:

  • Use styled components for static styles and dynamic styles that don't change very often;
  • Use inline styles (through .attrs) for styles that change frequently, like for animations.
like image 60
Raicuparta Avatar answered Oct 13 '22 00:10

Raicuparta