웹 애플리케이션에서 이야기하는 상태는 어떠한 의미를 지닌 값이며, 애플리케이션의 시나리오에 따라 지속적으로 변경될 수 있는 값을 의미한다.
상태로 분류 될 수 있는 것들
UI : 기본적으로 웹 애플리케이션에서 상태라 함은 상호 작용이 가능한 모든 요소의 현재 값 의미
ex) 다크/라이트 모드 , 라디오를 비롯한 각종 input, 알림창 노출여부
URL : 브라우저에서 관리되고 있는 상태값으로 URL 쿼리 파라미터를 의미한다
ex) https://www.airbnb.co.kr/34113796?adults=2
에서 adults=2 가 상태에 해당
폼(form) : 폼에도 상태가 존재한다
ex) 로딩중(loading),제출 여부(submit),접근 불가능한지(disabled), 유효값(validation)
서버에서 가져온 값: 클라이언트에서 서버로 요청을 통해 가져온 값도 상태
ex) API 요청
웹 서비스에서 점차 다양한 기능의 제공됨에 따라 웹 내부에서 관리해야 할 상태가 증가하고, 애플리케이션 전체적으로 관리해야 할 상태가 있다면 이것을 어디에, 어떻게 이것을 처리해주어야할지 생각해보자~
5.1.1 리액트 상태 관리의 역사
기존 mvc 패턴의 형태
- 뷰(HTML)가 모델(자바스크립트)을 변경할 수 있으며, 반대의 경우 모델도 뷰를 변경 가능
- 이는 코드를 작성하는 입장에서는 간단 할 수 있지만 코드의 양이 많아지고 변경 시나리오가 복잡하여 관리가 힘듬
Flux 패턴의 등장
페이스북 팀은 양방향이 아닌 단방향으로 데이터 흐름을 변경한다 이것이 Flux 패턴의 시작
Flux 패턴이란? 앱의 단방향 데이터 흐름(예측 가능, 선언적)을 촉진하는 시스템 아키텍쳐를 의미
액션(action) : 어떠한 작업을 처리할 액션과 그 액션 발생 시 함께 포함시킬 데이터를 의미한다. 액션 타입과 데이트를 각 정의해 디스패처로 본낸다
디스패처(dispatcher) : 액션을 스토어에 보내는 역할을 한다. 콜백 함수 형태로 앞서 액션이 정의한 타입과 데이터를 모두 스토어에 보낸다.
스토어 (store) : 여기에서 실제 상태에 따른 값과 상태를 변경할 수 있는 메서들 가지고 있다. 액션의 타입에 따라 어떻게 이를 변경할지 정의돼 있다.
뷰(view) : 리액트의 컴포넌트에 해당하는 부분으로, 스토어에서 만들어진 데이터를 가져와 화면을 렌더링하는 역할을 한다. 또한 뷰에서도 사용자의 입력이나 행위에 따라 상태를 업데이트하고자 할 수 있을것이다.
리액트는 대표적인 단방향 데이터 바인딩을 기반으로 한 라이브러리였으므로 이러한 단뱡향 흐름을 정의하는 Flux 패턴과 매우 궁합이 잘 맞았다 그렇기에 Flux 패턴을 따르는 다양한 라이브러리들이 많이 등작하기 시작했다
시장 지배자 리덕스의 등장
- 리덕스는 하나의 상태 객체를 스토어에 저장해주고, 이 객체를 업데이트하는 작업을 디스패치해 업데이트를 수행
- 이러한 작업은 reducer 함수로 발생시킬 수 있는데, 이 함수의 실행은 웹 애플리케이션 상태에 대한 완전한 복사본을 반환한 후 새롭게 만들어진 상태를 전파
- 리덕스로 인해 하나의 상태를 하위 컴포넌트로 깊이 전파해야 하는 props 내려주기 문제를 해결하고, 스토어가 필요한 컴포넌트라면 connect 만 쓰면 스토어에 바로 접근 가능
- 하지만 하나의 상태를 바꾸고 싶어도 해야 하는 일에 비해 보일러 플레이트가 너무 많다
Context API 와 useContext
- 리액트 16.3에서 전역 상태를 하위 컴포넌트에 주입할 수 있는 새로운 Context API 를 출시했다
- props 로 상태를 넘겨주지 않더라도 Context API를 사용하면 원하는 곳에서 Context Provider 가 주입하는 상태를 사용할 수 있게 된 것
- 16.3 버전 이전에도 context가 존재했으며, 이를 다루기 위한 getChildContext()를 제공
- 허나 이 버전의 방식은 상위 컴포넌트가 렌더링 되면 불필요한 렌더링이 일어날 수 있고, getChildContext를 사용하기 위해서는 context 를 인수로 받아야하는데 이때문에 컴포넌트와 결합도가 높아지는 단점이 있다
훅의 탄생 ,React Query 와 SWR
- 리액트 16.8 버전에서 함수 컴포넌트에 사용할 수 있는 훅 API 들이 추가되고, state를 매우 손쉽게 재사용 가능 하도록 만들어졌다
- 이후에 전에는 볼 수 없던 방식의 상태 관리가 등장 그것이 바로 React Query 와 SWR 이다
- 두 라이브러리 모두 외부에서 데이터를 불러오는 fetch 를 관리하는데 특화된 라이브러리지만, API 호출에 대한 상태 관리를 하고 있기 때문에 HTTP 요청에 특화된 상태 관리 라이브러리이다
- 기존에 우리가 알고 있던 상태 관리 라이브러리보다는 제한적인 목적으로, 일반적인 형태와는 다르지만 상태 관리 라이브러리의 일종이라 볼 수 있다.
- 두 라이브러리를 사용하면 생각보다 많은 상태를 관리하는 코드가 사라짐
Recoil,Zustand,Jotai,Valtio 에 이르기까지
- 훅이라는 새로운 패러다임의 등장에 따라, 훅을 활용해 상태들을 가져오거나 관리할 수 있는 다양한 라이브러리가 등장
- Recoil,Zustand,Jotai,Valtio 는 기존의 리덕스 같은 라이브러리와는 차이점이 있다 바로 훅을 활용해 작은 크기의 상태를 효율적으로 관리
- 모두 리액트 16.8 버전 이상을 요구하고 있고 물론 리덕스나 MobX 도 react-redux 나 mobx-react-lite 등을 설치하면 동일하게 훅으로 상태를 가져올 수 있지만 위 라이브러리들은 애초에 리액트와의 연동을 전제로 작동해 별도로 다른 라이브러리를 설치하지 않아도 된다는 차이점이 있다
- 개발자가 원하는 만큼의 상태를 지역적으로 관리하는 것 가능, 훅을 지원함으로 함수 컴포넌트에서 손쉽게 사용할 수 있다는 장점을 가지고 있다
5.1.2 정리
일정이나 여러가지 제반 환경이 여의치 않다면 익숙한 것을 선택해도 되지만, 다양한 옵션을 살펴보고 비교하면서 어떤 식으로 구현하고 있는지 살펴보는 것도 좋을 것이다.