공부를 하다보면 심심치 않게 redux에 대해 만나게 된다. 면접 준비를 하든, 앱 개발을 하든, 심지어는 테크 블로그를 읽게 되든.
redux가 전혀 뭔지 개념 없는 상태에서 한번 공부해 보기로 했다!
모든 정보는 이 포스트에 저장하고자 한다. 그래서 자주 업데이트할 예정입니다
많은 테크 블로그들을 보니, 두 문장으로 요약(?)할 수 있을 것 같았다.
역시 시작은 블로그를 통해서다(이 글을 읽는 당신도)
MVC 모델을 극복하기 위해 만들었다고 한다.
공부를 얼추 해보니 확실히 느꼈다. redux를 위해서는 flux를 꼭 먼저 이해해야한다(오래 안걸린다)
이야기를 좋아하는 저로써는 flux로의 카툰 안내서.. 너무 재밌어서 이것만 읽고 싶어질 지경이었습니다...
https://bestalign.github.io/cartoon-guide-to-flux/
번역본인데 꼭 읽어야합니다... 진심 두번 읽었슴다
어느 길거리의 가로등에 문제가 있다고 해보자
어떤 입안자(View)가 이를 해결할 대단한 생각을 해냈다!
1. 그래서 이 내용을 투고전문가(Action Creator)에게 이야기했다.
2. 감동받은 투고전문가(Action Creator)는 '공식 문서 형태'로 시청에 투고했다.
3. 공무원(Dispatcher)은 서식(들어온 순서)에 맞춰 정부기관(Store)에 보낸다.
4. 정부기관(Store)은 이를 보고 판단하여 일을 처리한다.
5. 정부기관(Store)는 중간직책에게 일이 처리됐음을 알리고, 포상한다
6. 중간 직책도 입안자에게 달려가 포상을 한다!
위 글을 보면 썩 괜찮은 행정국가라고 생각할 수 있겠다.
이 썩 괜찮은 행정국의 이름이 바로 Flux다!
View에 사용자의 Interaction이 들어왔다.
1. Action Creator에게 Action을 준비하라고 이야기한다
2. Action Creator는 Action을 포맷에 맞게 만들어 Dispatcher에게 제공한다
3. Dispatcher는 들어온 액션의 순서에 맞게 알맞은 스토어로 보낸다.
4. Store는 필요한 액션만 골라서 상태에 맞게 이를 수정한다
5. Store가 상태 업데이트를 완료하면 Controller View에 이 사실을 알린다
6. Controller View가 모든 View에게 새로운 렌더링 상태를 알린다
위처럼 flux는 다섯 친구(!)로 이루어져있는데 Store(정부기관), Dispatcher(공무원), Action Creator(투고 전문가), ControllerView(중간직책), View(입안자)가 이 주인공들이다.
이제 각자의 이름과 role만 외우면 된다(그래도 스정,디공,액투,콘중,뷰입 이런식으로 외우면 안된다)
위와 같은 형태가 나온 이유는 뭘까? MVC모델과 관련해서 거론되었던 문제들 중 하나는 인터랙션들이 너무 얽혀있어서 피곤하다는 것이다. (html javascript css 모델도 너무 많은 flow가 섞여 있어서 react가 나온 것으로 알고 있다)
그래서 이 모델 간의 interaction을 최대한 단순화하자! 라는 개념에서 출발한 것이 flux이다.
이렇게 간단한 모델으로 만든 것을 멋진 말로 '예측 가능' 하다고 한다.
가장 큰 차이는 핫 리로딩과 시간여행 디버깅이라고 하는데 위 두 가지를 이루기 위해서 redux가 생겨났다고 이해하면 된다.
문제점 1.
코드를 수정하고 저장했을 때, 데이터를 다시 입력하지 않고(즉 현재 상태를 유지하고) 변경된 앱이 로드되는 방식이다.
오,,! 앱 개발을 할 때 이런 방식을 확인한 것 같다(PlaceHolder 값만 바꿨는데, 입력한 데이터가 모두 날아가면 거 장난이 너무 심한거 아니오)
React는 원래 View와 액션 생성자는 핫 리로딩이 가능한데, 스토어(store)는 불가능하다고 한다. 이를 가능케 해주는 것이 redux!
스토어가 애플리케이션의 상태를 가지고, 상태 변환 로직은 리듀서가 관리하기 때문에 스토어의 핫 리로딩이 가능하다고 한다!
앱 실행 중간에 문제가 생기는 것을 발견했다고 하자 그럼 하나하나 다 할 수 없으니 한 스텝만 되돌리고 싶다. 이를 가능하게 해주는 기능이다.
예를 들면 다섯번째 입력에 문제가 발생한다면, 네번째 입력 상태로 돌아가고 싶은 것이다! 그리고 이런 액션이 다 저장되어서 QA도 효과적으로 가능하다고 한다
(6/25 업데이트중 -- 개념 이해 완료, 글을 다시 쓰기만 하면 된다!)
핫리로딩 문제 해결
바로 Store를 분리하는 것이다!
우리 Store(정부기관)씨는 현재의 상태와 상태변환 로직을 동시에 저장중이다. 이 때 상태 변환 로직을 변경하면, 상태마저 덧쓰이게 된다(즉, 저장해둔 상태가 날아간다)
그렇기 때문에, 상태와 상태변환 로직을 분리하는 것으로 이를 해결할 수 있다!(역시 삼권분립은 민주주의의 근본이다)
시간여행 디버깅 문제 해결
또한 시간여행 디버깅을 위해서는, 그 상태를 저장해야한다(그래야 돌아올 수 있으니까) Javascript의 동작 특성상(추후에 업데이트하겠음) 변수 저장만으로는 부족하다 (snapshot의 필요)
제대로 동작하려면 각 버전의 독립된 객체가 필요하다! 그래서 여러개의 Store를 만들 수 있어야한다
3Rd Party Plugin이 들어갈 곳이 없다
FLux는 Dispatcher의 업데이트와 Store의 업데이트를 구독해야하는데, 서드파티 모듈이 이해하기 어려운 개념이다.
그러니까 dispatcher를 완전히 감싸는 (혹은 통신을 가로채는 정도로 이해할 수 있곘다) 방법을 추가한다(우리는 이것을 미들웨어라고 부르기로 약속했어요)
또한 상태변환 로직을 트리로 만들어서 구조화 하자!
상당히 복잡해졌고, 프로그래머의 역량 중 하나는 '비유'이기 때문에 또 비유를 해 보겠다.
flux나라의 가로등 처리는 완벽했다. 하지만 두가지 문제가 있었는데,
1. 좋은 방법을 시도했는데, 주민들이 이걸 잘 모르고 계속 그 길을 이용하지 않는다. 신속하고 빠른 홍보가 필요한 시점이다(핫 리로딩)
2. 서류상으론 분명히 좋은 방안이었다. 근데 이전의 상태와 비교를 하고 싶은데, 그러려면 사진 같은걸로 남겨놔야하는데, 이를 처리하기에는 Store(정부기관)의 행정 시스템(JavaScript)가 완벽하지 않다.
그래서 Store(정부기관)을 분리하기로 마음 먹었다.
3. 한 편, 모든일을 Store(정부기관)에서 처리할 수 없으므로 외주를 맡기고 싶다. 진행상황이 정부기관과 공무원 사이에서는 진행되므로, 외부 업체가 이에 끼어들기가 까다롭다. 그래서 공무원이 외부업체에 메일을 보내면, 이 메일을 외부 업체가 Store(정부기관)에 보내는 것으로 해결하기로 했다.
이제 아래와 같이 바뀌게 되는 것이다. 역할이 조금 바뀐다
Store(정부기관), Dispatcher(공무원), Action Creator(투고 전문가), ControllerView(중간직책), View(입안자)
Action Creator(투고 전문가): 구조조정에서 살아남았다!
다만 이제 Dispatcher(공무원)한테 투고를 하는게 아니라 서식만 검수해주고 다시 돌려준다
Dispatcher(공무원): 실직!
다만 Store(정부기관)에 유지 편입되었다.
Store(입법부+행정부): 행정 변화로 모든 일을 혼자서 맡게 되었다. 상태가 변화되어야할 때 이를 Reducer(사법부)에게 물어보고, 최신 상태를 받아와 유지한다.
Reducer(사법부): 어떤 법을 적용해야하는지 알려준다.
독특한 구조인데, 실수하면 안되는 사법부의 특성상, 들어오는 모든 input을 복사, 조각 조각 내어 하위 Reducer들에게 보낸다.
이 output들을 다시 잘 합쳐서 새로운 상태를 만들고, 이를 Store(입법부+행정부)에 다시 돌려보낸다
Smart Component(구 ControllerView)()
Dumb Component(구 View)():
View Layer Binding:
참고 블로그:
핫리로딩&시간여행디버깅: https://bestalign.github.io/redux-hot-reloading-and-time-travel-debugging/
redux: https://jongmin92.github.io/2017/02/12/ReactNative/redux-for-starter/