리덕스
는 어렵습니다.
굳이 리덕스
를 사용해야 할까, 라는 의문이 드는 경우가 많아요. 하지만, 위에 물음을 던지기 전에, 내가 써보고 사용할 줄 아는 상태에서 이를 판단 해야하지 않을까 생각합니다. 조금 건방졌나요... 죄송합니다.
리덕스
를 왜 사용해야할까요? 상태관리를 한곳에서 하기 위해서? 결국에는 유지보수
를 위해서 사용한다고 생각해요. 간단한 프로젝트를 진행할 경우에는 사실 스테이트
, 프롭스
의 흐름을 파악하기가 쉽죠. 하지만 프로젝트가 복잡해지고, 컴포넌트
가 많아지게 된다면요. 아마, 어디서 문제가 생겼는지, 찾기가 쉽지 않을 거에요. 특히, 내가 작성한 코드가 아니라면요. 이를 해결 하기 위해서 리덕스
가 생겨났고, 많은 기업에서 사용하고 있지 않을까 합니다.
리덕스
를 통해서 컴포넌트
밖에서 스테이트
를 관리 할 수 있고, 이 덕분에 로직을 빨리 이해하고, 문제를 해결함에 있어서 용의해 진답니다. 그러면 코드
를 보면서 하나씩 이해해 보도록 하겠습니다.
코드를 연습할 때는, 제 개인적으로는 객체
형태의 값들을 다루는 것이 좋다고 생각해요. 왜냐하면 일반적으로 데이터를 단순히 하나의 값만을 받는 것이 아니라, 객체
에 담아서 받기 때문에, 객체
를 다루는 방법을 연습해야 한다고 생각해요.
habits
객체의 count
값을 변경하는 것을 리덕스
를 통해서 해볼거에요.
먼져 initialState
는 state
값이라고 생각하면 되요. 우리가 일반적으로 this.state
또는 const [state, setState]
사용할 때 처럼요. 그리고 버튼을 누를 때마다 setState
를 해서, 값을 변경 시킬거에요.
폴더
를 먼져 만들어 볼게요.
폴더
는 containers
, modules
만들거에요. 제 개인적으로는 actions
, reducers
, constants
를 따로 만드는 것 보다 modules
안에 다 넣어버리는게, 코드의 흐름을 이해하는데, 더 좋더라구요. 그래서 저는 modules
를 사용하겠습니다.
action type
설정을 해볼거에요. action
은 우리가 처음 설정한 state
의 값을 변경하고 싶을 때, 실행시키는 움직임이라고 생각하면 될 것 같아요. 그리고 action
은 하나의 객체
로 나타내고, 그 안에는 type
이 있어야 해요. type
은 실행할 action
을 결정지어주는 표지판
같은거에요. 여기서 꼭 생각해야 할 것은 type
이 있어야 하고, 객체
라는 것을 꼭 염두해두어야 해요. 객체
이기 때문에 우리는 type
뿐만 아니라, 다른 것들도 객체
안에 실어서 보낼 수 있어요. payload
라고 하는데, 저는 여기에서는 payload
대신에 좀 더 직관적으로 이해할 수 있도록 id
라고 할 거에요.
다시 정리를 하면, 먼져 액션이 발생할 수 있도록 타입을 설정하고, 그 타입에 따라서 액션이 생성할 수 있도록 액션 객체 함수를 만들어 줍니다. 그리고, 초기 상태값을 설정해 줍니다.
action
을 실행하면 그다음은 어떻게 할까요? 어떻게 변화시킬건지, 로직이 필요하죠. 그 로직이 담겨 있는게 reducer
랍니다. action
객체를 파라미터
로 받아서 그것을 갖고 로직을 만들면 된답니다.
하나씩 살펴보면, switch
문으로 작성이 되어있습니다. 이거는 case
즉, type
에 따라서 로직
을 다르게 실행하겠다는 의미랍니다.
type
이 INCREASE
일 때, 나는 return
을 할 건데, ...state
를 통해서 초기값
을 복사해 옵니다. 그리고, habits
라는 객체를 map
함수를 통해서 habit 객체
의 id
와 action 객체
의 id
가 같으면, 객체
안의 count
값을 1 올려주겠다, 라고 로직을 만들어준답니다. DECREASE
도 똑같습니다. 그러면, 이제 로직
을 다 만들었어요.
이렇게 만든 reducer
를 우리는 store
에 저장을 합니다. 근데, 여기서 알아야할 부분은, 하나의 reducer는 하나의 store만을 이용할 수 있다
입니다. 지금은 reducer
를 하나만 만들었지만, 프로젝트가 복잡해지고, 컴포넌트
가 많아지면, 당연히 reducer
도 많아진답니다. 그러면 이렇게 많아지는 reducer
를 하나로 만들어주어야만 store
에서 쓸 수 있는데 이를 도와주는 것이, combineReducers
랍니다.
combineReducers
는 위 폴더에서 index.js
에 넣어주면 된답니다. 이제 redux
를 쓸 준비가 되었습니다.
그러면 이제 store
를 만들어볼게요. 위에서 redux
를 쓸 준비를 해두었고, 이제 이것을 store
에 저장을 해야 해요. 그래서 여기에서 꺼내서 쓰는거죠.
복잡해도... 이렇게 만들어졌으니... 이렇게 써야줘...
createStore
를 통해서 store
를 만들어줍니다. 그리고 이 store
를 Provider
를 통해서 우리가 작업을 하고 있는 App
에 store
를 , 즉 우리가 위에서 만든 로직들을 넣어주면 된답니다. composeWithDevTools
는 Redux
의 흐름을 파악해게 해주는 굉장히 고마운 툴? 이랍니다. 이거는 나중에 설명을 할게요. 그러면 진짜 redux
를 쓸 준비가 다 되었습니다.
영화를 생각해 볼게요. 감독이 action
이라고 하면, 배우들이 연기를 해요. 그러면 어떠한 사건들이 일어나죠. 그거와 같습니다. 우리는 앞에서 만들었던거는 시나리오이구요 이제 action
을 통해서 배우들이 연기를 하게끔 해야겠죠. 감독이 되는 과정이 필요해요. 즉, action
을 외치는 감독이 필요한데, dispatch
가 그 역할을 한답니다. 이제 dispatch
를 만들어보겠습니다.
위의 코드는 containers
폴더안에 HabitsContainer
라는 파일로 만들었답니다. 왜? containers
라는 폴더를 따로 만들어서 했을까요? 사실 pages
의 Habits
파일 안에 다이렉트로 넣어줘도 되는데, 로직
부분을 따로 빼서, 코드의 흐름을 좀 더 빨리 이해하기 위함인 것 같아요. 저도 이러한 코드흐름을 벨로퍼트 선생님
의 책을 통해서 확인한 부분이라, 깊게 설명을 드릴 수는 없지만, container
를 사용하지 않으니, 확실히, 코드가 지져분해 보이긴 하더라구요. 그래서 제 개인적으로는 container
로 빼는게 좋다고 생각합니다. 그러면 하나씩 살펴볼게요.
mapStateToProps
는 이전의 상태값, 즉 초기값
과 같습니다. 이 초기값을
Props
로 이 HabitsContainer
에 넘겨주는거죠. 그리고 mapDispatchToProps
는 dispatch
를 통해서 action
을 일으키는 것이라고 생각하면 됩니다. 다시 말하면, action 생성 함수
를 Props
로 넘겨주는 거랍니다. 그리고 이러한 것들을 우리는 HabitContainer
와 연결을 시켜줘야 한답니다. 그 때 우리는 connect
를 사용한답니다. 이렇게 connect
를 사용하면 우리가 만들어 둔 로직을 store
에서 꺼내 쓸 수가 있는거죠. 여기서 mapDispatchToProps
에 대해서 조금 더 설명을 하면, action 객체
를 파라미터
로 넣어서, store
에 있는 함수를 호출하는데, 이 때 파라미터
즉, 우리가 id
, 즉 payload
를 파라미터
로 넣어서, 호출을 해줘야 합니다. 여기서 또 말씀드릴 부분은 onIncrease
와 onDecrease
를 modules
에서 export
해서 가져온답니다. 이거는 함수를 가져오는거지 state
를 가지고 오는게 아니에요. 이 state
는 mapStateToProps
를 통해서 가지고 오는거라는거... 다시 말씀드리고 싶었어요... 가끔 왜 onIcrease
와 onDecrease
만 export
해왔는데... habits
는? 이런 의문을 가진 질문들이 있어서요.
이제는 모두 끝났습니다. 버튼
과 이 로직들을 연결만 해주면 된답니다. HabitContainer
에서 Habits
로 다시 Habit
으로 넘겨 주면 된답니다. 물론, 그냥 Habit
으로 가서 써도 되는데 저는 로직의 흐름
이 보이게끔 코드를 만드는게 좋더라구요...
아래는 버튼을 클릭했을 때, state
의 변화를 ReduxDevTools
를 통해서 확인을 한거랍니다. 크롬 웹 스토어에서 Redux DevTools
를 설치한 다음에, yarn add redux-devtools-extenstion
을 설치해 주면, 확인 할 수 있답니다. redux
를 쓰면 반드시 써야 하는 툴이니 꼭 설치하시기 바랍니다.
Hooks
를 통해서 사용하면 훨~씬 간단하게 할 수 있는데, 우리가 해야할 것은 먼져 간단하게 사용하는 것 보다, 로직을 이해하는 것이 우선이라고 생각했어요. 로직을 이해한다면, 사실 코드를 복사를 한다고 해도, 바로 이해가 될 것이고, 그것을 나 또는 회사에 맞도록 커스텀 하는 것은 어렵지 않다고 생각해요. 저는 아직 모벡스는 사용해 보지 않아서 잘 모르겠지만, 주위 개발자분들이 리덕스를 사용할 줄 알면, 모벡스는 쉽게 사용할 수 있다고 하니, 조만간 한 번 사용해볼 예정이에요. 저와 같은 주니어분들이 가장 어려워 하는게 사실 리덕스인데, 객체에 대해서 그리고 로직의 흐름을 좀 더 이해를 한다면, 쬐~끔 더 수월하게 사용할 수 있을 것 같아요.
잘 읽었어요!! 미들웨어 편 기대하고 있겠습니다 문주님~~🤗