Emotion Styled Component Cascading 문제

Emotion에서 Styled Component 를 사용하면 해당 컴포넌트의 클래스 이름이 재정의된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const StyledTabPanel = styled.div<TabPanelProps<"div">>`
padding: 5px;
border: 2px solid hsl(219deg 1% 72%);
border-radius: 0 5px 5px;
background: hsl(220deg 43% 99%);
min-height: 10em;
min-width: 550px;
overflow: auto;
display: ${(props) =>
props.dataIndex === +(props.id?.slice(-1) as unknown as number)
? "block"
: "none"};
`;

function TabPanel({ children, className, ...restProps }: TabPanelProps<"div">) {
const { selected, setSelected } = useTabsContext();

return (
<StyledTabPanel
role="tabpanel"
tabIndex={0}
dataIndex={selected}
className={className}
{...restProps}
>
{children}
</StyledTabPanel>
);
}

styled component를 사용하여 TabPanel 컴포넌트를 생성하였다. 브라우저에서 해당 요소를 확인해보면 다음과 같이 알 수 없는 클래스로 나오는 것을 알 수 있다.

emotion styled component

TypeScript 오류 - 사용량 덮어씜

ts덮어씜

props를 생성하고 해당 props를 통해 styled Component에서 조건부 스타일을 주려고 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
type Component<T extends React.ElementType> = {
className?: string;
children?: React.ReactNode;
} & React.ComponentPropsWithRef<T>;

type TabPanelProps<T extends React.ElementType> = {
dataIndex?: TabsContextValue["selected"];
} & Component<T>;

const StyledTabPanel = styled.div<TabPanelProps<"div">>`
padding: 5px;
border: 2px solid hsl(219deg 1% 72%);
border-radius: 0 5px 5px;
background: hsl(220deg 43% 99%);
min-height: 10em;
min-width: 550px;
overflow: auto;
display: ${(props) =>
props.dataIndex === +(props.id?.slice(-1) as unknown as number)
? "block"
: "none"};
`;

function TabPanel({ children, className, ...restProps }: TabPanelProps<"div">) {
const { selected, setSelected } = useTabsContext();

return (
<StyledTabPanel
role="tabpanel"
tabIndex={0}
dataIndex={selected}
className={className}
{...restProps}
>
{children}
</StyledTabPanel>
);
}
  • 해당 타입을 정의할 때, 필수가 아닌 선택 사항으로 정의해주어서 해결하였다.
  • styled component 타입 지정 시 해당 컴포넌트의 props라고 지정을 해줘야지만 props에서 찾을 수 있다.

댓글 공유

📌 미션

  • Link 역할로써 span태그, img태그 확인
  • tabindex=”0”를 포함
  • img태그는 alt 속성으로 접근 가능한 이름 정의

🐒 문제

🤿 컴포넌트 props “as”를 img로 주면, img 태그로 렌더링 해주기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import styled from "styled-components";
import { goToLink } from "../../utils";

export function Link({ as = ComponentName, href, children }) {
const StyledLink = styled(`${as}`)`
... styles
`;
return (
<>
<StyledLink
tabIndex="0"
role="link"
onClick={(e) => goToLink(e, href)}
onKeyDown={(e) => goToLink(e, href)}
>
{children}
</StyledLink>
</>
);
}

Link.defaultProps = {
as: "span",
};
  • Link 컴포넌트 안에다가 styled-component를 생성하고 as props를 전달해주었다.

  • 위와 같이 할 경우, as props에 img 태그가 들어오게 된다면 컴포넌트 명명 규칙에 어긋난다고 나온다.

    이를 해결하기 위해 조건부 렌더링을 해주었다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import styled from "styled-components";
    import { goToLink } from "../../utils";

    export function Link({ as = ComponentName, href, children }) {
    const StyledLink = styled(`${as}`)`
    ... styles
    `;
    return (
    <>
    {as === "img" ? (
    <img
    tabIndex="0"
    role="link"
    onClick={(e) => goToLink(e, href)}
    onKeyDown={(e) => goToLink(e, href)}
    src="./gitprofile.jpeg"
    alt="W3C Website"
    />
    ) : (
    <StyledLink
    tabIndex="0"
    role="link"
    onClick={(e) => goToLink(e, href)}
    onKeyDown={(e) => goToLink(e, href)}
    >
    {children}
    </StyledLink>
    )}
    </>
    );
    }

    Link.defaultProps = {
    as: "span",
    };

    🐥 img가 업로드 되지 않는 문제

    • img 업로드 문제 해결

    문제의 원인은 npm 명령어로 webpack server만 실행시켰는데, webpack config.js 파일에 static 속성값을 [build]로 주었기 때문에 정적 이미지 파일을 불러오기 위해서는 build 폴더에서 assets을 찾는다.

    그러므로 npm run build 명령어로 build 폴더를 생성한 후 그 안에다가 img를 넣어주고 경로를 설정해주어 해결하였다.

    1
    2
    3
    4
    5
    6
    <Link
    as="img"
    alt="test이미지"
    src="./assets/img/gitprofile.jpeg"
    href="https://www.w3.org/WAI/ARIA/apg/example-index/link/link.html"
    />

    🐥 aria-label 속성 있을 때, 조건부로 css 추가 (삭제)

    이 속성을 삭제한 이유는 span 태그를 사용하여 Link 컴포넌트를 구현하였을 때, role="link"로 해주었기 때문에 aria-label 속성을 굳이 해주지 않아도 되므로 삭제하였다.

🏓 회고

  • styled-component를 사용하면서 어떻게 props를 받아서 App에서 렌더링 시켜야할지 헷갈렸었는데 직접 해보니 이해가 잘되었다.
  • 수업 시간에 배웠던 조건부 렌더링을 실제로 사용하면서 익히니 더욱 이해가 잘되었다. 역시 무언가를 만들어보면서 배우는 것이 힘들지만 더 도움되는 것 같다.

댓글 공유

  • page 1 of 1

loco9939

author.bio


author.job