24.07.06

강연주·2024년 7월 6일

📚 TIL

목록 보기
20/186
post-thumbnail

[CSS 모듈]


1. 이게 뭐지?

function Post({ post }) {
  return (
    <Card className={styles.post}>
      <div className={styles.content}>
        <ContentInfo user={post.user} updatedTime={post.updatedAt} />
        <p className={styles.description}>{post.content}</p>
      </div>
    </Card>
  );
}

< Card >는 아마도 별도로 정의된 리액트 컴포넌트일 가능성이 큽니다.
< div >는 일반적인 HTML 요소입니다.

{styles.post}는 CSS 모듈 문법입니다.
styles는 CSS 모듈 파일을 import하여 사용하게 되며,
styles.post는 CSS 모듈 파일에서 정의된 클래스 이름을 의미합니다.

2.
https://www.tcpschool.com/react/react_styling_cssmodule

React 컴포넌트에서 해당 CSS 파일을 불러올 때 선언된
CSS 클래스명은 모두 고유한 이름으로 자동 변환됩니다.
고유한 클래스명은 파일 경로, 파일 이름, 원래 작성한 클래스명, 해쉬값 등을 사용하여 자동 생성됩니다.
따라서 CSS Module을 사용하면 CSS 파일마다
고유한 네임스페이스를 자동으로 부여해 주기 때문에
각각의 React 컴포넌트는 완전히 분리된 스타일을 보장받게 됩니다.

외부 파일의 CSS를 가져와 사용 시, 다른 파일에 동일한 이름의 CSS 클래스가 있는 경우 중복 적용되는 것을 방지하기 위해 사용.

CSS 클래스를 불러올 때 클래스명을 고유한 이름으로 자동 변환해줌으로써 클래스명이 중첩되는 현상을 막아준다.


3. use case

FirstModule.js는 FirstModule.css를 import,
SecondMoudle.js는 SecondModule.js를 import해 스타일을 적용할 때,
각각 모듈에 동일한 wrapper 클래스명 때문에
First와 Second 모두 같은 스타일로 렌더링되므로
아래처럼 수정하면 된다는 말씀입니다.

  • import styles from "./FirstModule.module.css";
  • < div className={styles.wrapper} >
import styles from "./FirstModule.module.css";

const FirstModule = () => {
  return (
    <div className={styles.wrapper}>
      <h1>Hello, React!</h1>
    </div>
  );
};

export default FirstModule;
  • import styles from "./SecondModule.module.css";
  • < div className={styles.wrapper} >
import styles from "./SecondModule.module.css";

const SecondModule = () => {
  return (
    <div className={styles.wrapper}>
      <h1>Hello, React!</h1>
    </div>
  );
};

export default SecondModule;

➡️ 컴포넌트에서 CSS Module을 불어와 저장할 때 사용한
styles라는 이름 대신에 어떠한 이름을 사용해도 괜찮습니다.
예제에서는 일반적으로 많이 사용하는 styles를 사용했을 뿐이며,
다른 이름을 사용해도 무방합니다.

최종적으로 렌더링된 웹 페이지를 개발자 도구로 확인해 보면
각 컴포넌트에 적용된 클래스명이 wrapper라는 이름이 아닌,
해시(hash) 값이 뒤에 붙은 고유한 클래스명 또는 클래스 등을 이용해 고유한 클래스명으로 변경되어 있는 것을 확인할 수 있습니다.


4. 장단점

  • 장점
  1. 동일한 클래스명의 재정의로 인한 스타일의 전역 오염 방지.
  2. 자동으로 고유한 클래스명으로 변환해주기 때문에 클래스명을 짓기 위한 개발자의 고민을 줄여줌.
  3. 컴포넌트 단위로 스타일을 관리할 수 있어서 스타일 유지보수 용이.
  • 단점
  1. 모듈마다 별도의 CSS 파일을 작성해야 하기 때문에
    별도로 많은 CSS 파일을 만들어 관리해야 한다.
  2. 클래스를 동적으로 추가할 경우 최종 렌더링된 결과물에서
    자동 변환된 클래스명이 코드의 가독성을 어지럽히는 경우 발생.

[Styled Components vs CSS Module]

https://velog.io/@yeonjin1357/React-Styled-components-VS-CSS-Module


[query status]

useQuery() 실행 시 실제로 받아온 값이 있는지를
pending, error, success로 나타낸다.
각각 isPending, isError, isSuccess과 매칭해 현재 상태를 확인!

[fetch status]

그럼 이건?
queryFn() 함수가 현재 실행되는 중인지 아닌지 나타낸다.
fetchStatus 값을 통해 확인!

얘도 query status와 마찬가지로 총 3가지 상태를 가지는데,
'fetching', 'paused', 'idle'가 되겠다.

  • fetching : 현재 쿼리 함수가 실행되는 중
  • paused : 쿼리 함수가 시작은 했으나 실제로 실행되고 있지 않음
    e.g.네트워크가 오프라인이 된 경우
  • idel : 쿼리 함수가 어떤 작업도 하고 있지 않은,
    fetching도 paused 상태도 아닌 경우

[query life cycle]

먼저 처음으로 컴포넌트가 마운트되어 useQuery()가 실행되면,
데이터를 아직 받아오지 못했기 때문에 query status는 'pending'이 됩니다. 그리고 쿼리 함수가 실행되면서 fetch status는 'fetching' 상태가 되죠.

만약 네트워크 상태가 오프라인일 때 쿼리 함수가 실행된다면,
fetch status는 'paused' 상태로 가게 됩니다.

데이터를 성공적으로 받았다면 query status는 'success'가 되고, 만약 데이터를 받아오는 과정에서 에러가 발생했다면 'error' 상태가 됩니다.

fetch status는 데이터를 성공적으로 가져왔는지 여부에 상관없이,
쿼리 함수의 실행이 끝나면 'idle' 상태가 되고요.
그 후에 데이터를 서버에서 다시 받아오는 refetch 작업이 발생하면
쿼리 함수가 재실행되면서 다시 'fetching' 상태로 가게 됩니다.

이처럼 query status와 fetch status는 엄연히 독립적인 상태이기 때문에,
상황에 따라 query status와 fetch status가
다양한 조합의 형태로 나타날 수 있습니다.

이상적인 상황에서는 "pending & fetching" 상태에서 "success & idle" 상태가 되겠지만, 에러가 발생하는 경우 "error & idle" 상태가 될 수도 있고요. "success & idle" 상태에서 데이터를 refetch하게 되면
"success & fetching" 상태가 되기도 합니다.

이처럼 query status와 fetch status 값을 잘 활용하면, 다양한 상황에 맞춰 디테일한 구현을 할 수 있습니다.

profile
아무튼, 개발자

0개의 댓글