10장 상태관리, 11장 CSS in JS

iberis2·2024년 10월 26일
0

상태

리액트 어플리케이션에서의 상태는 렌더링에 영향을 줄 수 있는 동적인 데이터 값을 말한다.

React로 사고하기

어떤 게 state가 되어야 할까요? 아래의 세 가지 질문을 통해 결정할 수 있습니다.

  • 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.
  • 부모로부터 props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.
  • 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? 그렇다면 절대로 state가 아닙니다!
    그 외 남는 건 아마 state일 겁니다.

지역 상태 : 컴포넌트 내부에서 사용되는 상태

  • useState, useReducer 로 관리

전역 상태 : 앱 전체에서 공유하는 상태

  • createContext, 전역 상태 관리 라이브러리(Redux, Zustand, Jotai, MobX 등)

서버 상태 : 외부 서버에 저장해야하는 상태

  • tanstack-query, SWR 등 외부 라이브러리로 관리

시간이 지나도 변하지 않는다면 상태가 아니다

시간이 지나도 변하지 않는 값을 사용하기 위해 객체 참조 동일성을 유지하기 위해
적절한 접근 방식 : useRef 사용

Ref로 값 참조하기
컴포넌트가 일부 정보를 “기억”하고 싶지만, 해당 정보가 렌더링을 유발하지 않도록 하려면 ref를 사용하세요.

비적절한 접근 방식 ① : useMemo

useMemo 는 재렌더링 사이에 계산 결과를 캐싱할 수 있게 해주는 React Hook 입니다.
성능 최적화를 위해서만useMemo를 사용해야 합니다. 이 기능이 없어서 코드가 작동하지 않는다면 근본적인 문제를 먼저 찾아서 수정하세요. 그 후 useMemo를 사용하여 성능을 개선해야 합니다.

비적절한 접근 방식 ② : useState의 초깃값만 지정해서 사용
useState(() => new Store()) useState 의 초기값을 콜백함수로 지정하여 객체 인스턴스가 사용될 때 생성되도록(지연 초기화 방식)을 사용하는 것은 기술적으로는 잘 동작할 수 있지만 의미론적(상태 : 렌더링에 영향을 주며 변화하는 값)으로 객체 참조 동일성을 유지하기 위해 useState 를 사용하는 것은 적절하지 않다

부모로부터 전달받은 props 또는 state나 props로 계산된 값은 상태가 아니다

단일 출처 원칙 : 어떠한 데이터도 단 하나의 출처에서 생성하고 수정해야 한다

다른 값에서 파생된 값을 상태로 관리하게 되면 기존 출처와는 다른 새로운 출처에서 관리하게 되는 것이므로 해당 데이터의 정확성과 일관성을 보장하기 어렵다.

useState vs useReducer

state 로직을 reducer로 작성하기

  • reducer를 사용하면 코드를 조금 더 작성해야 하지만 디버깅과 테스트에 도움이 됩니다.
  • reducer는 반드시 순수해야 합니다.
  • 각 action은 단일 사용자 상호작용을 설명해야 합니다.

상태관리 라이브러리들

  1. top down 방식 : 모든 상태를 한 번에 보고 관리 - redux, zustand
  2. bottom up : 범위별로, 국소적으로 필요한 상태부터 작은 단위로 올라가면서 관리 - recoil, jotai
  3. 상태를 가변으로 관리, 필요할 때 꺼내 쓰고 구조는 직접 class 로 구성 - mobx , valtio
  4. url 로 상태관리 - useQueryparams (ex: 에어비엔비)

CSS in JS vs CSS in CSS

특징CSS-in-JSCSS-in-CSS
유연성JavaScript와 결합해 동적으로 스타일을 조작할 수 있어 조건부 스타일링과 컴포넌트 재사용에 유리별도의 스타일시트를 사용해 HTML과 스타일의 분리가 가능하며, 다양한 페이지와 컴포넌트에 재사용 용이
컴포넌트 단위 관리스타일을 컴포넌트 단위로 추상화하여 각 컴포넌트 내에서 스타일을 유지보수할 수 있음스타일을 컴포넌트 외부에서 관리해야 하며, 스타일시트를 수정할 때마다 CSS 파일을 직접 업데이트해야 함
부모와 독립성스타일 상속이 되지 않아 부모 요소로부터 독립적인 스타일을 유지할 수 있음명시적으로 정의하지 않는 한 상위 요소의 스타일을 자동으로 상속 받음
스코프 관리CSS로 컴파일될 때 고유한 이름이 생성되어 선택자 충돌이 방지됨하나의 전역 네임스페이스를 가지므로 선택자 충돌 위험이 있으며, 네이밍 규칙(BEM 등)이 필요함
성능런타임 시 CSS가 생성되어 초기 로딩 성능에 영향을 줄 수 있음CSS 파일을 미리 로드하여 성능에 유리
디버깅 용이성JavaScript 코드와 CSS가 통합되어 있어 개발 환경에 따라 디버깅이 쉬움CSS는 개발자 도구에서 직접 확인할 수 있어 CSS만의 문제를 독립적으로 디버깅하기 용이
벤더 프리픽스라이브러리가 자동으로 벤더 프리픽스를 추가하여 브라우저 호환성 유지에 유리직접 벤더 프리픽스를 작성해야 하며, 유지보수가 번거로울 수 있음
상수 및 함수 공유JavaScript 변수, 상수, 함수를 스타일 코드 내에서 쉽게 사용 가능하여 스타일 관련 로직을 통합 관리할 수 있음CSS 코드와 JavaScript 간에 상수나 함수 공유가 어려우며, 별도의 관리가 필요
빌드와 유지보수JavaScript 빌드 과정에 포함되어 전체 빌드 복잡도가 증가할 수 있음스타일시트를 독립적으로 관리하므로 HTML/CSS 구조가 분리되어 유지보수가 수월
사용성 및 도입 용이성JavaScript 지식만 있으면 사용 가능하여 도입이 쉬운 편CSS와 HTML의 기본 지식을 가진 사람에게 친숙하고 도입 장벽이 낮음
대표 라이브러리Styled-components, Emotion, JSSSass, Less, PostCSS

참고 : 우아한 타입스크립트 10장, 11장
리액트 공식문서

profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글