What is redux? (2) Redux 배경 및 구성 요소

Redux에 대한 개념을 저의 나름의 언어로 정리한 글입니다.

1. 개발이 편한 Redux

초기 Facebook에서 Flux 패턴을 간단하게 구현해 두었다. 하지만 dispatch 부분만 구현해두어서 완전한 Flux 패턴을 구현해두었다고 할 수 없었다. 그렇기 때문에 이후에 많은 개발자들이 Flux 패턴을 구현한 라이브러리를 만들었다. Redux도 이런 흐름 속에서 만들어진 라이브러리 이다. Redux는 2015년에 Dan Abramov에 의해서 React + Flux 구조에 Reducer를 더해진 Flux 라이브러리를 개발했다. Redux란 이름도 Reducer + Flux로 합쳐져서 개발되었다.

하지만 많은 Flux 기반 라이브러리에서 어떻게 Redux가 많은 사람들의 선택을 받게 되었는 지 작성해보려고 한다. Redux가 선택되는 가장 큰 이유는 개발을 편하게 도와주는 hot reloadingtime 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가 선택되었다.

2. 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은 아래와 같다.

  1. 기존 state와 action을 통해서 새로운 state가 생성된다.
  2. state는 immutable하게 업데이트 된다.
  3. side effect가 발생하면 않된다.

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가지가 존재한다.

  1. Provider component
  2. Component tree를 감싸는 Compoent
import { Provider } from 'react-redux'

ReactDom.render(
  <Provider store={store}>
    <APP />
  </Provider>
)
  1. connect() or useSelector(), useDispatch()
  2. connect()에서는 Component에서 state와 dispatch을 받아서 props로 전달하는 역할을 한다.
  3. useSelector()와 useDispatch()는 함수형 component에서 hook을 이용해서 state와 dispath를 전달하는 역할을 한다.
  4. selector
  5. state에서 특정 부분에서 가져올 수 있는 역할을 한다.
const selectCounterValue = (state) => state.value

참고 자료

https://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


Written by@WHALE
Fun Coding

GitHubFacebookLinkedIn