What is the use case of Styled-Components' .attrs() function?
Asked Answered
A

6

23

I came across the .attrs() function in styled components, but I do not understand what it does, or what it does differently?

I tried to understand the example in their docs, but as far as I am concerned, I can do the exact same thing without the attrs() function.

Could somebody please explain this to me or give a simple example?

Allegro answered 30/5, 2019 at 12:57 Comment(0)
V
30

Focus on naming is very important.

Styled components as the name suggests are for styling the native DOM elements or custom components.

attrs is for mentioning the attributes of that very same DOM element in the attrs constructor without the need to even mention it in actual component call.

What above line means is you can do

 <Input placeholder="A small text input" />

with

const Input = styled.input.attrs(({ type }) => ({
  type:  type || "password"
}))`
  align-items: center;
  display: flex;
  margin: 1.5vh 0;
`

See that component usage <Input .../> doesn't have type prop anywhere. It came from your attribute constructor function(static)

You couldn't have done this otherwise in your style rules because these are just the string literal of your CSS properties.

It saved you from writing type='password' in every usage of

<Input type='password' ... />

Bonus:

Now, that's a specific input component with type attribute of password. What if you wish to have a general input (styled component) with any value of type attribute?

Tada!


const Input = styled.input.attrs(({ type }) => ({
  
  type:  type || "password",
  ...

Your type is now dynamic i.e. it will take whatever input type prop you specify from your usage of component and render the input as that type (text, password, file etc. ) or if you skip the type prop it will pick up default of password. You can use as much conditional logic as you want up there.

Example:

<Input .../> // renders type="password"
<Input type="text" .../>
<Input type="email" .../>

Hope that answers your question.

Verjuice answered 30/5, 2019 at 13:48 Comment(0)
D
6

The goal of .attrs is so it can be passed down from your props. So you can use props inside your styled, and you can create placeholders, or change colors depending of the props etc...

For example :

const InputText = styled.input.attrs({
  type: 'text',
  placeholder: props => props.placeholder || 'Please fill',
})`
  padding: 6px 12px; 
`;
Delsiedelsman answered 30/5, 2019 at 13:31 Comment(2)
Thanks for your answer. So attrs() is mainly for HTML attributes, nothing to do with CSS? Or am I misunderstanding this?Allegro
That can be use in both case. For example you can use the HTML attribute 'active' using your props, you could say "if i clicked on this tabulation menu add active class to my html". Or you can use the attrs to make a ternary into your CSS, for example you can say "if you have more than 20 votes, color me the text in green", and this is CSS :)Delsiedelsman
B
4

Another interesting use is code organization. Styled-components only work with the style prop but many custom components don't expose this prop. Instead they provide a *Style prop which is passed to child component style props.

As an example react-native-material-textfield has 5 style props. enter image description here

We use the attrs function to keep the organization of styles in one file with the rest of the styled components.

styled-component attrs example

This doesn't allow the use of traditional css syntax for the pseudo component but it's the best we could think of to keep all styles organized.

Beulahbeuthel answered 23/5, 2020 at 3:22 Comment(0)
L
0

The goal is to add new props/modify input props (as an HoC) only to a specific styled component.

Please notice:

As of styled-components v4 the withComponent API is now a candidate for deprecation. In all likelihood, you probably want to use the new "as" prop to simply switch what element/component being rendered since the withComponent API is destructive toward styles if the lowest-wrapped component is a StyledComponent.

Lodmilla answered 30/5, 2019 at 13:23 Comment(0)
S
0

From the documentation:

When to use attrs?

You can pass in attributes to styled components using attrs, but it is not always sensible to do so.

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:

const PasswordInput = styled.input.attrs(props => ({
  // Every <PasswordInput /> should be type="password"
  type: "password"
}))``

// This specific one is hidden, so let's set aria-hidden
<PasswordInput aria-hidden="true" />
const PasswordInput = styled.input.attrs(props => ({
  // Every <PasswordInput /> should be type="password"
  type: "password"
}))``
// This specific one is hidden, so let's set aria-hidden
<PasswordInput aria-hidden="true" />

The same goes for props that can be inferred based on the "mode" of another prop. In this case you can set a property on attrs to a function that computes that prop based on other props.

Snubnosed answered 6/10, 2020 at 13:46 Comment(0)
D
0

I read the answer https://mcmap.net/q/560854/-what-is-the-use-case-of-styled-components-39-attrs-function What about native defaultProps? Where styled.attrs better?

interface PageProps {
  foo?: string;
  bar: number;
}

const PageComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>Hello, {props.foo}, {props.bar}</span>
  );
};

PageComponent.defaultProps = {
  foo: "default"
};
Dreadful answered 27/11, 2023 at 10:59 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewReisinger

© 2022 - 2024 — McMap. All rights reserved.