August 28, 2020
Redux에 대한 개념을 저의 나름의 언어로 정리한 글입니다.초기 Facebook에서 Flux 패턴을 간단하게 구현해 두었다. 하지만 dispatch 부분만 구현해두어서 완전한 Flux 패턴을 구현해두었다고 할 수 없었다. 그렇기 때문에 이후에 많은 개발자들이 Flux 패턴을 구현한 라이브러리를 만들었다. Redux도 이런 흐름 속에서 만들어진 라이브러리 이다. Redux는 2015년에 Dan Abramov에 의해서 React + Flux 구조에 Reducer를 더해진 Flux 라이브러리를 개발했다. Redux란 이름도 Reducer + Flux로 합쳐져서 개발되었다.
하지만 많은 Flux 기반 라이브러리에서 어떻게 Redux가 많은 사람들의 선택을 받게 되었는 지 작성해보려고 한다.
Redux가 선택되는 가장 큰 이유는 개발을 편하게 도와주는 hot reloading과 time travel debugging으로 볼 수 있다.
Hot reloading
Hot reloading은 상태를 다시 불러오는 기능이다. 이 기능이 중요한 이유는 코드 수정할 때, 이전 상태를 유지하면서 빠르게 수정이 가능하도록 도와준다는 것이다. Hot reloading 기능은 적용 되지 않는 다면, 코드가 수정되면 페이지를 다시 불러오고 기존에 있는 state는 초기 state로 업로드되어 사라지게 된다. 그렇기 때문에 새롭게 이전 state를 직접 설정해 두어야 한다. 하지만 Redux는 Hot reloading을 통해서 자동으로 이전 state를 유지하도록 도와준다.
Time travel debugging
Time travel debugging은 이전의 특정 시점의 state로 돌아갈 수 있도록 하는 기능이다. 만약 어떤 특정 상태 시점에서 에러 발생할 경우, Time travel debugging을 통해서 해당 시점을 저장하고, 해당 시점에서 상태로 되돌려서 디버깅을 쉽게 하도록 도와주낟.
State와 State 변화 로직 주의 할점은 Redux에서만 Hot reloading가 가능한 건 아니다. 하지만 Redux가 더 편하게 Hot reloading이 되도록 해준다. 이는 Redux에서는 Store에서 state 저장소와 Reducer란 State 변화 로직을 분리해서 관리하기 때문이다. 만약 하나로 합쳐져 있을 경우에는 State 변화 로직을 reloading할 때, state도 업데이트하기 때문에 기존의 정보도 잃어버리게 된다. 하지만 Redux에서는 역할이 분리되기 때문에 State 변화 로직만 reloading하여 state를 유지하도록 도와준다.
이런 기능 덕분에 다양한 Flux기반 라이브러리에서 Redux가 선택되었다.
Redux는 이전에 사용한 Flux 역할을 기반으로 만들어 졌다. 하지만 몇몇 부분에서 Flux와 다른 부분이 존재한다. 그렇기 때문에 그 차이와 형태를 작성해보려고 한다.
2-1. Action Creator
Flux와 Action Creator와 같은 역할을 한다. 다만 다른 점은 기존 Flux는 dispatcher에 보냈지만 Redux에서는 뷰에서 받은 값을 Action 포맷으로 변경해서 View에 다시 전달한다.
# Action : type와 payload를 property를 가지고 있다. type은 action의 이름이고, payload는 action생성에 필요한 데이터이다.
const addTodoAction = {
type: 'todos/todoAdded',
payload: 'Buy milk'
}# Action Creators : 액션 포맷으로 변환해주는 함수
const addTodo = text => {
return {
type: 'todos/todoAdded',
palyload: text
}
}2-2. Store
Flux에서는 다수의 Store를 가질 수 있지만 Redux에서는 단 하나의 Store만 가진다. 여기서는 State와 State tree를 유지하는 역할과 기존 flux의 dispatcher 역할을 담당한다. flux의 Store 역할은 Reducer에게 위임한다. 이렇게 변경한 이유는 이전에 설명한 Hot reloading과 time travel debugging 문제를 해결하기 위해서 이다.
# Store : state와 state tree를 유지하는 역할을 한다.
import { configureStore } from '@reduxjs/toolkit'
const store = configureStore({ reducer: counterReducer })2-3. Reducer
이제는 Redux의 핵심 요소인 Reducer에 대해서 설명한다. 이전에 설명했다시피 flux의 store 역할을 담당한다. State을 업데이트 할 때에는 몇가지 Rule에 의해서 업데이트 된다. Rule은 아래와 같다.
Flux의 Store은 수평적인 구조로 이루어져 있지만, Reducer는 트리 구조로 이루어져 있다. Reducer는 Root reducer를 가지고 있으며, 액션이 발생하면 상위 계층에 있는 Root reducer로 보내고 root reducer가 하위 reducer로 보낸다.
# Reducer : state와 action을 받고 새로운 state를 업데이트하는 함수
const initialState = { value: 0 }
function counterReducer(state = initialState, action) {
// Check to see if the reducer cares about this action
if (action.type === 'counter/increment') {
// If so, make a copy of `state`
return {
...state,
// and update the copy with the new value
value: state.value + 1
}
}
// otherwise return the existing state unchanged
return state
}2-4. Container Component, Presentation Component
Container Component는 flux의 controller view 역할을 담당한다. Presentation Component는 flux의 view 역할을 한다.
2-5. The View layer binding
Redux에서는 스토어와 View를 연결하기 위한 작업이 필요하다. 이런 작업을 하는 컨셉이 3가지가 존재한다.
import { Provider } from 'react-redux'
ReactDom.render(
<Provider store={store}>
<APP />
</Provider>
)const selectCounterValue = (state) => state.valuehttps://redux.js.org/tutorials/essentials/part-1-overview-concepts https://blog.naver.com/backsajang420/221371244288 https://d2.naver.com/helloworld/1848131 https://velog.io/@velopert/Redux-1-%EC%86%8C%EA%B0%9C-%EB%B0%8F-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC-zxjlta8ywt https://medium.com/@wooder2050/%EB%A6%AC%EB%8D%95%EC%8A%A4-redux-%EB%8A%94-%EC%99%9C-%EC%93%B0%EB%8A%94-%EA%B1%B4%EB%8D%B0-2eaafce30f27