Styled Component ReferenceError: Cannot access 'Component' before initialization
Asked Answered
T

2

9

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

Towline answered 24/6, 2021 at 1:15 Comment(1)
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?Breathy
A
6

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>
    );
}
Ashwin answered 11/9, 2021 at 14:31 Comment(1)
Josh, your fan here. Actually I followed your article to implement this.Towline
S
0

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

Shirline answered 24/6, 2021 at 2:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.