- 학습 내용
이번에 학습한 내용은 프론트엔드 개발에서의 상태 관리이다. 그중에서도 특히 react에서의 상태 관리를 학습했다. 상태는 변하는 데이터인데, 컴포넌트 단위로 개발을 할 때 컴포넌트의 개수가 적으면 이 상태 관리에 큰 어려움이 없지만, 컴포넌트가 많아지면 상태 관리가 여간 복잡한 것이 아니다. 그래서 이 복잡한 상태 관리를 상태 관련 라이브러리를 통해 하게 된다. 그중에서도 이번에 학습한 것은 Redux이다. 이번 시간에는 프론트엔드 개발에서의 상태 관리와 상태 관리 라이브러리를 사용하는 이유, 그리고 Redux의 기초적 내용을 학습하고자 한다.
- 프론트엔드 개발에서의 상태 관리
상태는 변하는 데이터이다. 특히 UI, 프론트엔드 개발에서는 동적으로 표현되는 데이터를 상태라고 한다. 컴포넌트 범위에 따라 이 상태를 구분해보면 특정 컴포넌트 안에서만 관리되는 상태인 로컬 상태와 프로덕트 전체 혹은 여러 컴포넌트에서 관리되는 상태인 전역 상태로 구분할 수 있다. 로컬 상태의 경우 특정 컴포넌트 안에서만 관리되는 상태이다. 컴포넌트 내에서만 영향을 끼치는 것이다. 그래서 컴포넌트와 데이터를 공유하지 않는 폼 데이터는 대부분 로컬 상태이다. input box, select box 등이 이러하다.
전역 상태는 다른 컴포넌트와 상태를 공휴하고 영향을 끼치는 상태이다. 예를 들어 쇼핑앱에서 장바구니에 물품이 담길 경우 상품 선택 여부에 따라 총 주문 금액을 업데이트해야 한다. 장바구니에 담긴 물품은 그 개수 등을 다른 컴포넌트에서 전달해줘야 하는데, 이 경우가 전역 상태라고 할 수 있다. 사실 전역 변수의 경우 남용하는 것이 좋지 않다. 왜냐하면 혼동을 주어 관리에 어렵기 때문이다. 그러나 전역 상태는 경우에 따라 필요할 때가 많다. 서로 다른 컴포넌트가 사용하는 상태의 종류가 다르면 꼭 전역 상태일 필요가 없지만 서로 다른 컴포넌트가 동일한 상태를 다루면 이 출처는 오직 한 곳이어야 하기 때문이다. 만약 출처에 사본이 있다면 두 데이터는 서로 동기화하는 과정이 반드시 필요하기 때문에 문제를 어렵게 만드는 것이다. 이 것은 CORS에서 나왔던 데이터의 무결성을 위해서도 아주 중요한 문제이다. 동일한 데이터는 항상 같은 곳에서 데이터를 가져와야 신뢰성이 확보되기 때문이다.
또 상태를 다를 때 주요 고려대상 중 하나로 Side Effect가 있다. Side Effect란 함수의 입력 외에도 함수의 결과에 영향을 미치는 요인을 말한다. 대표적으로 네트워크 요청이나 API 호출이 Side Effect이다. React의 주요 개발 원칙 중 하나가 UI를 페이지 단위가 아닌 컴포넌트 단위로 보는 것인데, 컴포넌트를 만들 때 최대한 Side Effect를 배제하고 만들어야 한다. 그러나 앱을 만들다 보면 API를 호출하거나 그 외 Side Effect가 불가피하게 발생할 수 있다. 이런 상태를 side effect 의존적인 상태라고 한다.
이런 상태 관리를 돕는 툴들이 바로 상태 관리 라이브러리이다. 대표적으로 React Context, Redux, MobX가 있다. 이런 툴들은 전역 상태 저장소를 제공하고, Props drilling 이슈를 해결한다. Pops drilling 이슈란 여러 컴포넌트가 있을 때 A라는 컴포넌트에 상태가 있을 때, B라는 컴포넌트에서 해당 상태를 사용한다고 하면 그 중간에 껴있는 다른 여러 컴포넌트들에도 props를 만들어 자식 컴포넌트로 넘겨줘야 한다. 이런 문제를 해결해 주는 것이다.
- 왜 상태 관리 라이브러리가 필요한가?
그러면 상태 관리 라이브러리를 사용하는 이유를 좀 더 상세히 살펴보자면, 상태 관리 라이브러리는 무조건 필요한 것은 아니다. 그러나 규모가 큰 앱에선 있는 게 확실히 편하다. 심지어 react 16.3에서부턴 Context API가 더욱 좋아져서 글로벌 state 관리가 별로의 라이브러리 없이 할 수 있게 되었다. 그럼에도 이미 Redux와 같은 상태 관리 라이브러리의 유용함으로 이것을 통한 프로젝트가 무수히 많다. 이 때문에 이것을 익히는 것이 필수적이라고 볼 수 있다. 특히 상태 관리 라이브러리를 사용하면 복잡한 상태 업데이트 로직들을 컴포넌트에서 뜯어낼 수 있고 이를 모듈화 할 수 있다. 모듈화를 한다면 여러 파일들로 저장해서 보기 좋게 정돈할 수 있기 때문에 더욱 높은 유지 보수성을 얻을 수 있다. 또한 상태 관리 라이브러리가 없으면 컴포넌트가 지닌 setState를 사용해서 열심히 상태를 조합하고 이를 여러 컴포넌트를 거쳐 props로 전달해주고 해야 하는데 상태 관리 라이브러리는 이런 작업을 훨씬 쉽게 해주는 것이다.
- Redux
Redux란 상태 관련 라이브러리이다. 보통 개발을 하다 보면 복잡하게 얽힌 많은 수의 컴포넌트 때문에 상태 변경 로직이 복잡하게 얽혀있는 경우가 많다. 그러나 상태 변경 로직을 컴포넌트로부터 분리하면 표현에만 집중한 보다 단순한 함수 컴포넌트를 만들 수 있다. 바로 Redux가 이런 상태 변경 로직을 컴포넌트로부터 분리해주는 역할을 한다. Redux의 장점은 상태를 예측 가능하게 만들어 준다. Reducer는 순수 함수이기 때문에 다음 상태가 어떻게 될지 쉽게 예측할 수 있다. 둘째로 유지보수에 용이하다. 복잡한 컴포넌트가 아닌 Redux를 이용해서 Action과 state의 로그를 기록하면 Action이 생겼을 때 어떤 일이 생겼는지 추측이 가능하기 때문에 디버깅에 아주 유리하다. 마지막으로 테스트를 붙이기 쉬운데, 이 역시 순수 함수를 사용하기 때문이다.
- Redux에서 사용하는 Action, Reducer, Store의 의미와 특징
1) Store
상태가 관리되는 오직 하나의 공간을 말함. 컴포넌트와 별개로 공간을 따로 두어 그 공간 안에 앱에서 필요한 state를 두고 컴포넌트에서 state가 필요할 때 그 공간에 접근해서 state를 가져오는 것이다. 이 공간이 Store이다.
2) Action
자바스크립트 객체인데, 이 객체 안에 타입을 비롯한 다양한 데이터들이 담긴다. 이 Action은 Store에게 앱의 데이터를 운반해주는 역할을 한다.
2) Reducer
Action이 Store에서 앱의 데이터를 운반하는 과정 중에 반드시 통과해야 하는 것이 있는데, 이것이 Reducer이다. Store에 current state가 있을 때 Action을 통해서 새로운 state를 만드는 과정으로 Dispatch에 Action 객체가 전달되고, Dispatch는 Reducer를 호출한다. 이 과정을 통해 new state가 생성된다.
위의 그림은 브라우저에서 +버튼을 클릭하면 이벤트가 발생하면 Dispatch의 전달 인자로 Action 객체를 담아서 Reducer로 전달된다. 그러면 Reducer는 Action 객체의 타입과 데이터에 따라서 동작하고 그 결과로 새로운 State를 만들어낸다.
- Redux의 3가지 원칙과 주요 개념과의 연결
Single source of truth | 동일한 데이터튼 항상 같은 곳에서 가져 온다. 그래서 Redux는 데이터를 저장하는 하나의 공간인 Store를 둠. |
State is read-only | React와 같이 state를 변경할 때 반드시 setState를 사용한 것처럼 Redux에선 Action이라는 객체를 통해서 변경이 가능함. |
Changes are made with pure functions |
변경은 순수함수만으로 가능하다는 뜻으로 Reducer와 연결되는 개념이다. |
- Presentational 컴포넌트와 Container 컴포넌트
1) Presentational Component
Presentational Component는 오직 뷰만을 담당하는 컴포넌트이다. 이 안에는 DOM 엘리먼트, CSS와 같은 스타일을 가지고 있으며, Presentational Component 또는 Contatiner Component를 가지고 있을 수도 있다. 그러나 Redux의 Store에 직접적인 접근 권한이 없고 오직 props로만 데이터를 가지고 올 수 있다. 또한 대부분의 경우 state를 가지고 있지 않다. 가지고 있다면 보통 데이터에 관련된 것이 아닌 UI에 관련된 것이다. 주로 함수형 컴포넌트로 작성된다. 만약 state를 가져야 하거나 최적화를 위 LifeCycle이 필요하면 클래스형 컴포넌트로 작성된다.
2) Container Component
Container Component는 Presentational Component들과 Container Component들을 관리하는 것을 담당한다. 주로 내부에 DOM엘리먼트가 직접적으로 사용되는 경우는 없다. 만약 사용된다면 그냥 감싸는 용도로만 쓰인다. 또한 CSS 스타일을 가지면 안 된다. 스타일은 Presentational Component에서 정의되어야 한다. 대부분 state를 가지며 Redux에 직접적으로 접근할 수 있다.
- 느낀 점
이번 파트를 학습하면서 실무에서 필요로 하고 사용해야 할 기술들이 이런 것이구나 느꼈다. 그와 함께 앞으로 이런 기술들과 쏟아져 나오는 더 발전된 기술들을 잘 활용하는 것이 현업에서 중요한 덕목이겠구나 느꼈다.
'React' 카테고리의 다른 글
잘못된 useState 사용 줄이기 (0) | 2023.03.08 |
---|---|
useState 동기적으로 사용하기 (0) | 2022.11.08 |
React 컴포넌트 디자인 (0) | 2021.11.25 |
React 기초3 state & props (0) | 2021.08.26 |
React 기초2 라우터(Router) (0) | 2021.08.13 |