리액트 어플리케이션에서의 상태는 렌더링에 영향을 줄 수 있는 동적인 데이터 값을 말한다.
어떤 게 state가 되어야 할까요? 아래의 세 가지 질문을 통해 결정할 수 있습니다.
- 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.
- 부모로부터 props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.
- 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? 그렇다면 절대로 state가 아닙니다!
그 외 남는 건 아마 state일 겁니다.
지역 상태 : 컴포넌트 내부에서 사용되는 상태
전역 상태 : 앱 전체에서 공유하는 상태
서버 상태 : 외부 서버에 저장해야하는 상태
시간이 지나도 변하지 않는 값을 사용하기 위해 객체 참조 동일성을 유지하기 위해
적절한 접근 방식 : useRef 사용
Ref로 값 참조하기
컴포넌트가 일부 정보를 “기억”하고 싶지만, 해당 정보가 렌더링을 유발하지 않도록 하려면 ref를 사용하세요.
비적절한 접근 방식 ① : useMemo
useMemo 는 재렌더링 사이에 계산 결과를 캐싱할 수 있게 해주는 React Hook 입니다.
성능 최적화를 위해서만useMemo를 사용해야 합니다. 이 기능이 없어서 코드가 작동하지 않는다면 근본적인 문제를 먼저 찾아서 수정하세요. 그 후 useMemo를 사용하여 성능을 개선해야 합니다.
비적절한 접근 방식 ② : useState의 초깃값만 지정해서 사용
useState(() => new Store()) useState 의 초기값을 콜백함수로 지정하여 객체 인스턴스가 사용될 때 생성되도록(지연 초기화 방식)을 사용하는 것은 기술적으로는 잘 동작할 수 있지만 의미론적(상태 : 렌더링에 영향을 주며 변화하는 값)으로 객체 참조 동일성을 유지하기 위해 useState 를 사용하는 것은 적절하지 않다
단일 출처 원칙 : 어떠한 데이터도 단 하나의 출처에서 생성하고 수정해야 한다
다른 값에서 파생된 값을 상태로 관리하게 되면 기존 출처와는 다른 새로운 출처에서 관리하게 되는 것이므로 해당 데이터의 정확성과 일관성을 보장하기 어렵다.
- reducer를 사용하면 코드를 조금 더 작성해야 하지만 디버깅과 테스트에 도움이 됩니다.
- reducer는 반드시 순수해야 합니다.
- 각 action은 단일 사용자 상호작용을 설명해야 합니다.
| 특징 | CSS-in-JS | CSS-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, JSS | Sass, Less, PostCSS |
참고 : 우아한 타입스크립트 10장, 11장
리액트 공식문서