8

While Referencing another component in the styled Component I am getting this error

ReferenceError: Cannot access 'SiteHeader' before initialization

here is the code

//Common.ts

import styled from 'styled-components/macro';
import { SiteHeader } from '../Theme/Layout/Header';

export const Container = styled.div`
    padding: 0 15px;
    ${SiteHeader} & {
        padding-top: 20px;
        padding-bottom: 20px;
    }
`;

//header.tsx

import { Container } from '../../Styles/Common';
import styled from 'styled-components/macro';

export default function Header(): JSX.Element {
    return (
        <SiteHeader>
            <Container>
                {/*navigation*/}
            </Container>
        </SiteHeader>
    );
}

export const SiteHeader = styled.header`
    background: var(--green-kelp);
`;

M Adeel Ahsan
  • 183
  • 1
  • 9
  • I see this error a lot when extending components defined in different files. I think Styled Components should allow it, but they don't currently. As an alternative approach maybe build around their ThemeProvider functionality? – stakolee Sep 02 '21 at 13:40

2 Answers2

5

It looks like the problem here is that there's a circular dependency; Common.ts is importing header.tsx, and header.tsx is importing Common.ts. As a result, the build tool isn't able to work out which file should be parsed first, and SiteHeader isn't defined when it parses Container. It's a JS issue more than a styled-components issue.

The solution to this problem is to make sure imports only go in 1 direction. The easiest way to do this is to move SiteHeader into its own file:

SiteHeader.js:

const SiteHeader = styled.header`
    background: var(--green-kelp);
`;

export default SiteHeader

Common:

import { SiteHeader } from './SiteHeader';

export const Container = styled.div`
    padding: 0 15px;
    ${SiteHeader} & {
        padding-top: 20px;
        padding-bottom: 20px;
    }
`;

Header:

import styled from 'styled-components/macro';

import SiteHeader from '../SiteHeader';
import { Container } from '../../Styles/Common';

export default function Header(): JSX.Element {
    return (
        <SiteHeader>
            <Container>
                {/*navigation*/}
            </Container>
        </SiteHeader>
    );
}
Joshua Comeau
  • 2,594
  • 24
  • 25
0

This error appears when you try to style a Child component that has been defined after its parent.

ValenciaHQ
  • 381
  • 1
  • 13