Post

상태관리

상태 관리란 대체 뭘까 깊생을 해보자..

먼저 상태란 뭘까? React에서 말하는 상태란 렌더링 결과에 영향을 미치는 자바스크립트 값을 의미한다. 객체, 숫자, 문자열, 배열, 불린값 등 모든 것이 상태가 될 수 있다.

예를 들어 서버에서 갖고온 객체 목록도 상태고, 현재 로그인 한 사용자 이름도 상태고, 이 모달이 열려있는지 안 열려있는지도 상태다.

왜? 렌더링 결과에 영향을 주니까.

그럼 상태 관리란 뭘까? 시간 경과에 따른 상태의 변경 및 업데이트를 처리하는 프로세스다. 애초에 상태란 고정된 값을 갖지 않고 변화하는 값이다.

상태의 정의는 물리학 생물학 등 다양한 곳에서 정의되는데 공통적으로 시간에 따라 변화한다는 의미를 갖고있다.

로컬 상태 vs 전역 상태는 뭐가 다를까? 로컬 상태는 해당 컴포넌트와 그 하위 컴포넌트에서만 사용하는 상태고, 전역 상태는 앱 전체 어디서든 접근할 수 있는 상태다.

언제 전역으로 올려야 할까? 두 개 이상의 서로 관련 없는 컴포넌트 트리에서 같은 상태를 공유해야 할 때다. 예를 들어 로그인한 유저 정보는 헤더, 사이드바, 메인 페이지 등 여러 곳에서 필요하니까 전역으로 관리하는게 맞다.

만약 전역으로 관리하지 않는다면 props drilling이 발생할 수 있다.

props drilling이 뭘까? 상위 컴포넌트에서 하위 컴포넌트로 props를 전달할 때, 중간에 있는 컴포넌트들이 해당 props를 사용하지 않는데도 단순히 전달만을 위해 받아야 하는 상황이다.

내 친구가 5반에 있어서 쪽지를 전달해주려고 하는데 그냥 바로 5반에 안 가고 1반 -> 2반 -> 3반 부터 해서 쭉 가서 5반까지 타고 타고 간다는거다. 그니까 1반부터 4반은 쪽지가 필요 없는데도 굳이 받아서 다음 반으로 넘겨줘야 한다.

props drilling의 문제점은 뭘까?

첫째, 유지보수가 어려워진다. drilling이 5개가 있는데 prop 이름을 바꾸려면 중간 컴포넌트들도 다 바꿔줘야 된다. ((뭐 IDE로 한번에 바꿀 수는 있지만…))

둘째, 컴포넌트의 책임이 모호해진다. 중간 컴포넌트들이 자신과 관련 없는 props를 받게 되니까 이 컴포넌트가 뭘 하는 애인지 파악하기 어려워진다.

셋째, props가 변경되면 중간 컴포넌트들도 리렌더링이 일어날 수 있다. 물론 memo로 최적화할 수 있지만 추가 작업이 필요하다.

전역 상태는 어떻게 구현할 수 있을까? Redux, Zustand 같은 라이브러리를 쓰거나 React Context API를 사용할 수 있다.

Context API는 어떨까? React 자체 기능이라 별도 라이브러리 설치가 필요 없다. 하지만 Context value가 바뀌면 해당 Context를 구독하는 모든 컴포넌트가 리렌더링된다. 이게 성능상 문제가 될 수 있어서 여러 Context로 분리하거나 memo를 적절히 써야 한다.

전역에서 상태를 관리하면 props drilling이 줄어든다. 그럼 단점은 뭔가? 내가 클라이언트 상태를 전역에서 저장했는데 이게 서버 데이터랑 연관이 있는거라면 stale response가 발생할 수 있다. stale이란 “탁하다, 오래됐다”는 뜻이다. 물이 고이면 뭐라하죠? 탁한 물 탁한물은 다른 말로 뭐라고 하죠? 고인 물 안 좋게 말하면 썩은 물 걍 한마디로 데이터가 오래됐다는거다.

왜 이런 문제가 발생할까? 서버 데이터는 시간이 지나면서 바뀔 수 있는데, 클라이언트에서는 예전에 받아놓은 데이터를 계속 쓰고 있을 수 있다. 다른 사용자가 데이터를 수정했는데 내 화면에는 예전 데이터가 그대로 보이는 상황이 생긴다. 그래서 서버 상태 관리에는 특별한 전략이 필요하다. 언제 데이터를 다시 가져올지(refetch), 얼마나 오래 캐시할지, 에러가 나면 어떻게 재시도할지 등등을 고려해야 한다.

이런 복잡한 문제들을 해결해주는 라이브러리가 SWR이나 TanStack Query(구 React Query)다. 이 라이브러리들은 서버 상태만을 위한 전문 도구라고 보면 된다. 수동으로 구현하고 싶다면 특정 액션 후 데이터를 새로고침하거나, 폴링을 하는 등 직접 구현하면 된다.

근데 왜 굳이 라이브러리를 쓰냐?면 저기서 최적화랑 에러처리 등을 간단하게 할 수 있으니까.

그래서 전역 상태는 언제 쓰고 로컬 상태는 언제 쓰지? 정답이 없다 알잘딱이다

This post is licensed under CC BY 4.0 by the author.