简体   繁体   中英

Circular dependency for extracted styles with styled-components

I'm fairly new to styled-components and trying to extract / refactor styles to separate files. I have problem with circular dependency - probably because of lacks of experience in styled-components good practices. This is the situation:

// A.js
import { StyledA } from './styles';

export default () => (
  <StyledA>
    <SomeOtherComponent />
  </StyledA>
);

// B.js
import { StyledA1 } from './styles';

export default () => (
   <SomeWrapperComponent>
     <StyledA1 />
   </SomeWrapperComponent>
);

// styles.js
import styled from 'styled-components';
import A from './A.js';

export const StyledA = styled.div`...`;
export const StyledA1 = styled(A)`...`; // causes dependency circle error

What I'm trying to achieve, is to extend A component styles and keep it's children components (for file B.js ).

  • export const StyledA1 = styled(StyledA) doesn't work because I lose component A structure.
  • ...and import A in styles.js causes eslint "dependency-cycle" error because of imports A.js → styles.js → A.js .

What should I do to keep HTML structure of extended component and resolve dependency cycle issue?

When working with CSS-in-JS (like styled-components ) you usually keep the components generated by style in the same file .

So how do you export the className generated with CSS-in-JS constructor? By using compound components .

export const StyledA = styled.div`
  background: red;
  font-size: 20px;
`;

const A = ({ className }) => (
  <StyledA className={className}>
    <div>Display me always!</div>
  </StyledA>
);

// Can use any naming here
A.className = StyledA;

export default A;

Also, when you want to reuse styles , you create file like styles.js and declare reusable css blocks:

import { css } from 'styled-components';

const border = css`
  border: 2px black solid;
`;

export { border };

Full usage:

import A from './components/A';
import styled from 'styled-components';
import { border } from './components/styles';

const StyledA = styled(A)`
  background-color: palevioletred;
`;

const StyledASelector = styled.div`
  ${A.className} {
    background-color: paleturquoise;
    margin: 5px;
    ${border}
  }
`;

const App = () => {
  return (
    <>
      <A />
      <StyledA />
      <StyledASelector>
        <A />
      </StyledASelector>
    </>
  );
};

编辑有趣的-heyrovsky-sgujh

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM