
#1. Css-in-js / Styled.component 이거 왜 씀?
처음에 난 이거 왜 쓰는지 정말 몰랐다.
동적으로 스타일을 변경할때 쓰인다고 익히 들었지만 그것도 modules.css로 가능한것이었으니까 예로
import classes from '경로';
<div className={isActive ? classes.Active : undefined }>hello world</div>
이런식으로도 충분하게 가능한 부분이어서 별 필요성을 못느끼던 찰나
컴포넌트에서 props로 전달하고 그 props의 값을 이용해서 css in js의 스타일을 변경 할 수 있다는 것을 발견..
이는 굳이 상태 훅이나 따로 만들 필요없이 컴포넌트 내에서 css in js도 같은 props를 이용해서 css가 동적 할당이 가능하라는 뜻이다 (직관적이라는 뜻.)
이는 불필요한 로직이 필요가 없어지며, 또 내가 직접 클래스을 인에이블, 언에이블 명을 정하지 않아도 되는 작명의 고통에서 벗어 날 수 있다.
일반 HTML이라면 CSS는 DOM트리를 기준으로 랜더링을 구성하지만 React는 좀 다르다.
[HTML의 Style Sheet 생명주기]
1. HTML DOM트리 구성
2. CSS 로딩 _ ( HTML 요소에 어떠한 스타일을 적용할지 정의함 )
3. CSS 랜더링 트리 구성 _ ( HTML DOM트리에 따라 적용할 CSS의 랜더링 트리 구성)
3. Css 랜더링 트리 구성 > Paint _ ( 이 단계에 스타일이 반영되며 화면 출력함 )
[React 생명주기 ]
1. 함수컴포넌트 호출 useState , useQuery , useRef 등.. Hook 실행 _ ( useEffect 은 마지막에 실행)
2. 함수와 Hook의 구성을 통해서 가상 DOM 생성
3. Css-in-js 호출 JavaSciprt를 Css로 랜더링
( <head></head>안으로 <style>태그의 형태로 동적 삽입 )
4. JSX 스타일 할당 _ ( 이 시점에 css가 JSX 요소에 할당 )
5. 가상DOM을 사용하여 실제 DOM 랜더링 _ ( useEffect는 "마운트" 되는 시점인 랜더링 이후에 실행 )
Css in js 는 JavaScript를 거쳐서 Css가 할당되며, 훅이 재 실행되면 재 랜더링이 되기에 매번 JavaSciprt에서 css로 변환해야 한다. 이런 이유로 일반 css보다 성능면으로 안 좋을 수 있다.
#2. CSS-in-js 사용법
css-in-js 설치와 필요한 컴포넌트에서 import 해주자
npm install styled-components
import styled from 'styled-components'; // 스타일 컴포넌트 임포트
[예시1] button에 색상 입히기
const Mybutton = styled.button`
background: rgba(255,255,255,.7);
color: #fff;
`
return(
<>
<Mybutton/>
</>
)
간단한 button에 색상을 입히는 로직이다
styled.[element] 은 만들어질 element를 정의한다. styled.div, styled.li 이렇게 구성했다면 <div></div> <li></li> 형식으로 구성이 될 것이다.
[예시2] button에 prop로 동적 스타일 할당
const Mybutton = styled.button`
background: rgba(255,255,255,.7);
color: #fff;
${props => props.$visible && `color:blue`}
`
export default function Component(){
const [ visible , setVisible ] =useState(false);
return(
<>
<Mybutton
onClick={()=>setVisible(prev => !prev)}
$visible={visible}
/>
</>
)
}
보면 visible이라는 상태를 props로 전달해서 css in js 글씨 색상을 변경하고 있다.
한 스코프 내에서 props의 상태로 어떻게 css가 변경되는지 직관 적으로 확인 할 수 있다라는 점이 가장 큰 핵심이다.
[예시3] 외부 컴포넌트 스타일링
// OutsideComponent.js
export default function OutsideComoponent({className , children , ...props}){
return(
<>
<p>외부 컴포넌트!</p>
<div className={className} {...props}>{children}<div>
</>
)
}
// InsideComponent.js
import React, { useState } from 'react';
import styled from 'styled-components';
import OutsideComponent from './OutsideComponent';
const MyButton = styled(OutsideComponent)`
background: rgba(255, 255, 255, 0.7);
color: #fff;
${props => props.$visible && `color: blue;`}
`;
export default function Component() {
const [visible, setVisible] = useState(false);
return (
<>
<MyButton onClick={() => setVisible(prev => !prev)} $visible={visible}>
내부 컴포넌트!
</MyButton>
</>
);
}
css in js에서 스타일링 된 스타일들은 "className"으로 전달된다. class의 명이 곧 style 이기 때문에..
이렇게 className으로 매핑된 style들은 동적으로 삽입이 가능하고, 물론 onClick 또한 props로 '프롭스 드릴링' 형태가 되어
onClick으로 상위 컴포넌트인 setVisible을 핸들링 할 수 있다. _("styeld(컴포넌트)" 는 외부의 컴포넌트를 사용할때 주로 사용 )
#3. Css in js 사용 간에 이슈사항
React는 컴포넌트에 선언된 props들을 통해 전달 된 Props(attribute)를 통해 컴포넌트를 구성한다.
Css-in-JS또한 attribute를 의존하여 스타일을 변경하기에 보통 boolean 값을 이용해서 true, false값으로 를 판가름하여 스타일을 동적 반영한다.
const [ visible, setVisible ] = useState(false);
const Component = Styled.div`
${props => props.visible && 'color: red'}
`
<Component visible={visible}>Hello world</Component>
매우 유용하게 사용하지만 문제점이 있었다.
여기서 상태 훅을 이용해서 visible값을 전달하는데 Component에 visible={visible} 을 전달하여 스타일 적용하는 것까진 문제 없었다.
Css in js를 사용하다보면 자주 발생하는 이슈로 DOM에 직접 정의되지 않는 attribute에 값을 blooean으로 반영 하기 때문에 발생되는 오류였다.

이를 "transient props" 라는 "$" 접두사를 붙이게되면 오류를 막을 수 있었다.
props.$visible / $visible={visible}
'React' 카테고리의 다른 글
| [React-Hook-Form] watch ,reset ,setValue (0) | 2024.03.01 |
|---|---|
| [React-Query 사용하기] (1) | 2024.01.30 |
| [React-datePicker] 시작날짜, 종료날짜 컴포넌트 만들기 (1) (1) | 2024.01.27 |
| React - Router [ action , loader ] (2) | 2024.01.09 |
| React - useMemo (1) | 2023.12.09 |