HighlightCode.site 많관부바랍니다
이전 게시글인 라이브러리 없이 선택적 구독 구현하기 에서 전역 상태 관리 저장소를 바닐라로 구현하는 방법에 대해 기술했었다.
이번 주말간은 8개월 전에 만들었던 토이프로젝트를 대규모로 리팩토링하며 지냈는데
이번 리팩토링 목표는 구리구리한 리덕스를 덜어내고 리액트만으로 구성된 전역 상태 관리 저장소를 만드는 것이였다.
리덕스를 써야 할 만큼 상태 관리 패턴이 복잡하지도 않을 뿐더러 시간이 지나서 다시 리덕스를 만질려 하니 머리가 지끈거려
이전에 만들었던 전역 상태 관리 저장소 코드를 조금 수정하여 상태 관리 저장소를 만들어봤다.
현재 내 프로젝트에선 포맷팅 할 언어와 테마들을 리액트의 state 뿐 아니라 로컬스토리지에도 저장해야 하는 로직이 존재한다.
이전 리덕스를 사용 할 때에는 해당 상태를 구독하는 컴포넌트 내부에서 useEffect
를 통해 로컬 스토리지에서 값을 가져와 초기화 하고 , 상태가 변경되면 변경하는 함수에서 같이 localStorage
에 값을 업데이트 하곤 했다.
리덕스에서도 미들웨어를 제공하는걸로 알고 있으나 오랜만에 문서를 보려하니 머리가 너무 지끈거리더라
이에 리덕스에 존재하는 미들웨어 원리를 조금 참고하여 기존의 상태 관리 저장소 로직을 수정해봤다.
해당 코드가 상태 관리 저장소를 만드는 로직 외엔 아무런 로직이 존재하지 않는 가장 순수한 형태의 스토어 생성 로직이다.
클로저를 이용하여 호출하는 곳에서 매번 새로운 상태를 생성하는 것이 아니라 createStore
호출 시점에 생성된 객체를 바라보는 상태를 생성함으로서 선택적 구독과 전역 상태 관리 로직 모두 구현하였다.
대부분의 인터페이스는
zustand
를 따라 만들었다 보아도 무방하다.
로컬 스토리지를 관리하는 로직은 redux
의 미들웨어 아이디어를 차용했다.
리덕스에선 상태를 변경 시킬 액션이 디스패치 되기 전, 미들웨어에서 디스패치 된 액션을 이용해 처리 하고
처리 후의 액션을 다음 미들웨어 혹은 리듀서에게 넘겨주는 방식을 택했다.
나도 비슷하게 아이디어를 채용하여 다음과 같이 수정해주었다.
로컬 스토리지에 저장해야 할 상태의 키값들을 인수로 받아 미들웨어를 생성하는 메소드인 createLocalStorageMiddleware
메소드를 생성해주었다.
이로인해 생성된 미들웨어는 createStore
내부 setStore
에서 실제 상태를 저장하는 객체 값을 변경하기 전 미들웨어를 거쳐서 나온 새로운 상태값을 가지고 상태를 업데이트 하게 된다.
단순 CSR
기반의 리액트만 사용했다면 로컬스토리지에 접근하는게 자유롭지만
SSR
기반인 NextJs 에서 로컬 스토리지에 접근하기 위해선 useEffect
를 써줘야한다.
useEffect
를 이용하여 초기값을 갱신하는 로직도 미들웨어 때 처럼 생성해주었다.
우선은 상태 관리 로직들이 컴포넌트 단이 아니라 스토어 하나에 집중됨으로서
책임이 명확히 분리 된 거 같아서 좋은거로 보인다.
다만 미들웨어를 차용하는 것이 복잡성을 더 키우는 것은 아닐까?
스토어를 호출하는 커스텀 훅을 생성하고 그 커스텀 훅 안에서 처리하는 것이 더 리액스트럽지 않나? 라는 생각이 들기도 하고.. 뭐가 정답인지 잘 모르겠다.
간지는 나는데 ..
레딧에 올리면 코드 리뷰를 해주기도 한다는데 한 번 올려봐야겠다.