Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styled Component ReferenceError: Cannot access 'Component' before initialization

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);
`;

like image 472
M Adeel Ahsan Avatar asked Jun 24 '21 01:06

M Adeel Ahsan


1 Answers

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>
    );
}
like image 148
Joshua Comeau Avatar answered Sep 28 '22 08:09

Joshua Comeau