最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Styled Components - two different elements with the same styles - Stack Overflow

programmeradmin6浏览0评论

I have a Button component (in React) which can either be a button or an a element, depending on if a href prop is passed to the component. Something similar to below:

const Button = ({ children, href, onClick }) => {
    if(href) {
        return <a href={href} onClick={onClick}>{children}</a>;
    }

    return <button type="button" onClick={onClick}>{children}</button>;
};

I previously used Sass to style these components, but am now attempting to move over to styled-components. However, I have come across an issue where these two elements require the same styles, but the syntax of styled-components would require me to create to separate variables - styled.button and styled.a, with duplicated styles for each.

I was wondering if there was a way of dynamically changing the element used in styled-components, maybe based on props in the same way one can change individual CSS properties? I have attempted something along the lines of:

const StyledButton = styled((props) => props.href ? 'a' : 'button')`
    ...
`;

but no luck so far. Any advice would be greatly appreciated.

I have a Button component (in React) which can either be a button or an a element, depending on if a href prop is passed to the component. Something similar to below:

const Button = ({ children, href, onClick }) => {
    if(href) {
        return <a href={href} onClick={onClick}>{children}</a>;
    }

    return <button type="button" onClick={onClick}>{children}</button>;
};

I previously used Sass to style these components, but am now attempting to move over to styled-components. However, I have come across an issue where these two elements require the same styles, but the syntax of styled-components would require me to create to separate variables - styled.button and styled.a, with duplicated styles for each.

I was wondering if there was a way of dynamically changing the element used in styled-components, maybe based on props in the same way one can change individual CSS properties? I have attempted something along the lines of:

const StyledButton = styled((props) => props.href ? 'a' : 'button')`
    ...
`;

but no luck so far. Any advice would be greatly appreciated.

Share Improve this question asked Apr 30, 2020 at 8:31 rwacarterrwacarter 2,0043 gold badges16 silver badges29 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 15

Create generic styles that you can reuse

You can extract and pass styles as string args to a styled component.

const buttonStyles = `
color: red;
...
`

const StyledA = styled.a(buttonStyles);
const StyledButton = styled.button(buttonStyles);

If you need some exceptions

import styled, { css } from ‘styled-components’;

const baseInputStyles = css`
  padding: 0.5em;
`;

const StyledA = styled.a`
  ${baseInputStyles}
`;

const StyledButton = styled.button`
  ${baseInputStyles}
  /* make changes as needed*/
`;

I tried Joe Lloyd's answer but it didn't work because the function styled.xxx() takes one parameter of type templateStringsArray instead of template String:

const buttonStyles = [
`
color: red;
...
`
]

const StyledA = styled.a(buttonStyles);
const StyledButton = styled.button(buttonStyles);

Using the css helper is only justified when interpolating a function, not a string. In your case, it is more reasonable to use the polymorphic props as:

const Title = styled.h1`
      ...
    `;

    return (
      <Title>Some title</Title>
      <Title as='h2'>Some another title</Title>
    )

As in the other answers, you can create generic styles for this component, but from v4+, you can also use the as property to make a single component polymorphic. (See polymorphic prop in Styled's documentation).

An example of this:

const SomeButton = styled.button`
  border: red 1px solid;
`

function UsingSomeButtonAsALink(href) {
  return <SomeButton as={'a'} href={href}>Text</SomeButton>
}

In older versions of Styled, there was a similar polymorphic ability via the .withComponent API, but this was deprecated in v4 and removed completely in v6. The documentation no longer describes how to use this API.

发布评论

评论列表(0)

  1. 暂无评论