리덕스 코드를 읽었다. 5년 정도 사용한 것 같은데 어떻게 만들었는지는 모르고 있었다. 메뉴얼 문서에서 읽은 정보로 얕게 아는 정도였다. 자세한 구조에 대해서는 궁금하지 않았던 모양이다. 이렇게 호기심이 부족해서는 실력이 늘지 않는다. 10년동안 1년 차에 해당하는 경험을 10번 반복한 것이다.
리덕스 코드를 열어서 살펴 보았다. 생각보다 길지 않았다. 앉은 자리에서 커피 한 잔을 마시며 다 읽었다. 어딘가 문서에서도 코드가 짧다고 홍보했던 것 같다.
리덕스는 스토어를 만드는 함수 createStore를 제공한다. 사용자(개발자)는 이 함수로 어플리케이션만의 전용 스토어를 만들어 활용할 것이다. 스토어는 두 가지 메세지를 처리할 수 있다. 디스패치(dispatch)와 구독(subscribe).
디스패치는 스토어에게 상태를 변경하라는 메세지를 전달할 때 사용한다. 이를 액션이라고 부른다. 스토어는 액션에 따라 상태를 변경할 것이다.
스토어는 직접 상태를 변경하지 않고 리듀서(Reducer)에게 위임한다. 리듀서가 스토어를 변경할 수 있는 객체다. 리듀서는 어플리케이션마다 사용자가 직접 구현할 함수다. 그 동안 만들었던 리듀서 함수가 바로 이것이다. 액션에 따라 이전 상태를 적절하게 변경할 것이다.
리듀서가 액션을 처리하기 위해서는 구조화된 액션을 사용해야 한다. 타입(type)과 패이로드(payload). 타입은 액션의 종류로써 이것에 따라 리듀서는 상태를 변경할 것이다. 함께 전달된 페이로드는 다음 상태를 계산할 때 사용한다.
다시 스토어로 돌아오자. 스토어는 리듀서에게 메세지를 전달하고 변경된 상태를 받는다. 이전 상태와 비교해 변경되었지를 판단한다. 비교 로직이 꽤나 단순했다. 값을 비교. 이래서 리듀서를 순수함수로 만들라고 했나 보다. 인자를 변경해버리는 부수효과를 만들면 비교할 수 없으니깐. 그리고나서 이것을 스토어를 사용할 객체들에게 전파한다.
스토어의 변경은 구독 메서드를 이동한다. 상태가 변경되면 알려줘, 라고 하듯이 사용자는 콜백함수를 등록할 것이다. 물론 필요한 만큼 여러 개 등록할 수 있는 구조다. 스토어는 상태가 바뀌면 콜백함수 인자로 전달하고, 구독하고 있는 객체는 새로 갱신된 상태를 전달받게 될 것이다.
--
여기까지가 리덕스의 세부 구현 사항이다. 그럼 이제 궁금한 것은 리액트에서 어떻게 사용하는가이다. 스토어의 인터페이스를 보면 구독 함수를 이용할 것이라고 추론할 수 있다. 스토어가 바뀌었을 때 새로운 상태를 받아 리액트 렌더 사이클을 실행하면 스토어에 반응하는 뷰를 만들 수 있을 것이다.