JS' 공부흔적

[Redux] Vanilla Redux의 기본 개념 본문

Redux

[Redux] Vanilla Redux의 기본 개념

이준수 2022. 1. 19. 04:34

Redux는 Javascript의 상태 관리 라이브러리이다. 보통 React와 함께 많이 사용되지만, Augular, jQuery, vanilla JavaScript 등 여러 framework에서 사용이 가능하다. Redux에 기본적인 개념 및 용어를 알아보자.

 

npm install redux

yarn add redux

1. Store

Store는 state가 저장되는 공간이다. state는 변경되는 데이터를 말한다. 버튼을 누르면 숫자가 1 증가하거나 감소하는 프로그램이 있다고 할 때, 여기에서의 state는 변경되는 숫자이다. 이러한 state들을 저장하는 곳이 store이다. store는 아래와 같이 생성한다.

import { createStore } from 'redux'

const store = createStore()

그러나 이렇게만 한다고 끝나는 것이 아니다. Reducer라는 것도 만들어 줘야 한다.


2. Reducer

Reducer는 state를 변경하는 함수이다. Redux에서는 데이터가 store에 저장되고, reducer를 통해서 데이터가 변경된다. 따라서 reducer에 의해 변경된 데이터를 store에 저장해야 한다. reducer와 store를 같이 쓰면 아래와 같다.

import { createStore } from 'redux'

const reducer = (state = 0) => {
  return state
}

const store = createStore(reducer)

console.log(store.getState()) //0

reducer 함수에서 반환된 값이 store에 저장된 state 값이 됨을 알 수 있다.


3. dispatch & action

위에서 reducer 함수는 state를 변경한다고 했는데 실제로 변경하는 과정을 보자. 우선 state를 변경하기 위해 reducer 함수를 호출해야 한다. 이때 쓰이는 것이 dispatch라는 것이다. dispatch는 '보내다'라는 뜻을 가지고 있는데 실제로 reducer 함수에 action이라는 것을 보내는 역할을 한다. action은 객체이며 reducer에 접근하기 위해 필요한 것이다. action은 state에 변화가 필요할 때 발생한다. 결국 다시 말하면 store에 저장된 state를 변경하기 위해서 reducer에 action을 dispatch해야 한다. 아래 코드는 이를 보여준다.

import { createStore } from 'redux'

const PLUS = 'PLUS'
const MINUS = 'MINUS'

const reducer = (state = 0, action) => {
  switch (action.type) { //action의 type에 따라 수행하는 것이 다름
    case PLUS:
      return state + 1
    case MINUS:
      return state - 1
    default:
      return state
  }
}

const store = createStore(reducer)

store.dispatch({ type: PLUS }) //action은 객체이며, 이 action을 가지고 reducer에 접근한다.
store.dispatch({ type: PLUS })
store.dispatch({ type: MINUS })

console.log(store.getState()) //1

 

default state의 값은 0이고, PLUS가 2번, MINUS가 1번 발생했으므로 결론적으로 1이 로그에 찍히게 된다.


4. Subscribe

위에서 설명했던 것은 Redux에서 데이터를 수정하고 저장하는 방법에 대한 것이었다. 이렇게 수정한 데이터를 우리가 필요한 곳에 불러다 써야 한다. 이때 필요한 것이 subscribe이다. subscribe는 '구독하다'라는 뜻을 가지고 있다. 즉 특정 동작 A를 구독해서 데이터가 변화될 때마다 A를 수행하도록 하는 것이다. 그럼 직접 구현해보자. 아래에서 사용할 예제는 Redux에서 숫자를 1씩 더하거나 빼는 동작을 한 후에 이렇게 변화된 데이터를 화면에 나타내는 코드이다. (기본적인 Javascript 문법은 알고 있다고 가정하고 진행한다.)

<!DOCTYPE html>
<html lang="en">
 ...
  <body>
   <button id='plus'>Plus</button>
   <span></span>
   <button id='minus'>Minus</button>
  </body>
</html>
import { createStore } from 'redux'

const PLUS = 'PLUS'
const MINUS = 'MINUS'

const reducer = (state = 0, action) => {
  //action의 type에 따라 수행하는 것이 다름
  switch (action.type) {
    case PLUS:
      return state + 1
    case MINUS:
      return state - 1
    default:
      return state
  }
}

const store = createStore(reducer)

const plus = document.getElementById('plus')
const minus = document.getElementById('minus')
const number = document.querySelector('span')

const onChange = () => {
  number.innerText = store.getState()
}

store.subscribe(onChange) //데이터 변화가 감지될 때마다 onChange 함수를 실행

//plus 버튼을 눌렀을 때 PLUS action을 reducer로 보냄
plus.addEventListener('click', () => {
  store.dispatch({ type: PLUS })
})

//minus 버튼을 눌렀을 때 MINUS action을 reducer로 보냄
minus.addEventListener('click', () => {
  store.dispatch({ type: MINUS })
})

5. Action Creator

//plus 버튼을 눌렀을 때 PLUS action을 reducer로 보냄
plus.addEventListener('click', () => {
  store.dispatch({ type: PLUS })
})

//minus 버튼을 눌렀을 때 MINUS action을 reducer로 보냄
minus.addEventListener('click', () => {
  store.dispatch({ type: MINUS })
})

위 코드는 action을 발생시켜서 reducer로 접근하는 부분이다. 이때 구조를 좀 더 나누자면 Action Creator라는 함수를 만들 수 있다. 이 함수는 말 그대로 action을 생성하는 함수로 단순히 action을 dispatch한다. 따라서 위 코드에 Action Creator를 적용하면 아래와 같다.

//Action Creators : action을 가지고 reducer에 접근
const plusNum = () => {
	store.dispatch({ type: PLUS })
}

const minusNum = () => {
	store.dispatch({ type: MINUS })
}


//plus 버튼을 눌렀을 때 Action Creator 호출
plus.addEventListener('click', () => {
  plusNum()
})

//minus 버튼을 눌렀을 때 Action Creator 호출
minus.addEventListener('click', () => {
  minusNum()
})

 

실행 결과는 아래와 같다.

 

728x90
반응형