리액트 없이 쓰는 리덕스

리덕스는 리액트에 종속되는 그런 라이브러리가 아닙니다. 물론 리액트에서 쓰기위해 만든거니 궁합은 매우 잘맞죠! 한번, 평범한 HTML 와 JavaScript 환경에서 리덕스를 사용해가면서, 리덕스의 기본 개념을 배워봅시다.

우선, JSBin(https://jsbin.com/) 을 열으세요.

우리는 간단한 카운터를 구현해보겠습니다. HTML 섹션엔 다음과 같이 입력해보세요.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>그냥 평범한 리덕스</title>
</head>
<body>
  <h1 id="number">0</h1>
  <button id="increment">+</button>
  <button id="decrement">-</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
</body>
</html>

그럼 이러한 결과가 만들어집니다.

자, 이제 자바스크립트를 작성 할 것입니다! 주석을 아주~ 상세하게 적어놓았으니, 주석도 함께 읽어가면서 자바스크립트를 작성해보세요.

// 편의를 위하여 각 DOM 엘리먼트에 대한 레퍼런스를 만들어줍니다.
const elNumber = document.getElementById('number');
const btnIncrement = document.getElementById('increment');
const btnDecrement = document.getElementById('decrement');

// 액션 타입을 정의해줍니다. 
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// 액션 객체를 만들어주는 액션 생성 함수
const increment = (diff) => ({ type: INCREMENT, diff: diff });
const decrement = () => ({ type: DECREMENT });

// 초기값을 설정합니다. 상태의 형태는 개발자 마음대로 입니다.
const initialState = {
  number: 0
};

/* 
   이것은 리듀서 함수입니다.
   state 와 action 을 파라미터로 받아옵니다.
   그리고 그에 따라 다음 상태를 정의 한 다음에 반환해줍니다.
*/

// 여기에 state = initialState 는, 파라미터의 기본값을 지정해줍니다.
const counter = (state = initialState, action) => {
  console.log(action);
  switch(action.type) {
    case INCREMENT:
      return { 
        number: state.number + action.diff
      };
    case DECREMENT:
      return { 
        number: state.number - 1
      };
    default:
      return state;
  }
}

// 스토어를 만들 땐 createStore 에 리듀서 함수를 넣어서 호출합니다.
const { createStore } = Redux;
const store = createStore(counter);


// 상태가 변경 될 때 마다 호출시킬 listener 함수입니다
const render = () => {
  elNumber.innerText = store.getState().number;
  console.log('내가 실행됨');
}

// 스토어에 구독을하고, 뭔가 변화가 있다면, render 함수를 실행합니다.
store.subscribe(render);

// 초기렌더링을 위하여 직접 실행시켜줍니다.
render();


// 버튼에 이벤트를 달아줍니다.
// 스토어에 변화를 일으키라고 할 때에는 dispatch 함수에 액션 객체를 넣어서 호출합니다.

btnIncrement.addEventListener('click', () => {
  store.dispatch(increment(25));
})


btnDecrement.addEventListener('click', () => {
  store.dispatch(decrement());
})

이제 버튼들을 눌러보시면 숫자가 변경 될 것입니다. 지금까지 한 작업들을 정리해봅시다.

  1. 액션타입을 만들어주었습니다.
  2. 그리고 각 액션타입들을 위한 액션 생성 함수를 만들었습니다. 액션 함수를 만드는 이유는 그때 그때 액션을 만들 때마다 직접 { 이러한 객체 } 형식으로 객체를 일일히 생성하는 것이 번거롭기 때문에 이를 함수화 한 것입니다. 나중에는 특히, 액션에 다양한 파라미터가 필요해 질 때 유용합니다.
  3. 변화를 일으켜주는 함수, 리듀서를 정의해주었습니다. 이 함수에서는 각 액션타입마다, 액션이 들어오면 어떠한 변화를 일으킬지 정의합니다. 지금의 경우에는 상태 객체에 number 라는 값이 들어져있습니다. 변화를 일으킬 때에는 불변성을 유지시켜주어야 합니다.
  4. 스토어를 만들었습니다. 스토어를 만들 땐 createStore 를 사용하며 만듭니다. createStore 에는 리듀서가 들어갑니다. (스토어의 초기상태, 그리고 미들웨어도 넣을 수 있습니다.)
  5. 스토어에 변화가 생길 때 마다 실행시킬 리스너 함수 render 를 만들어주고, store.subscribe 를 통하여 등록해주었습니다.
  6. 각 버튼의 클릭이벤트에, store.dispatch 를 사용하여 액션을 넣어주었습니다.

리덕스의 작동 흐름에 대하여 조금 감이 잡히셨나요? 그럼 이제 리액트에서 리덕스를 사용해봅시다!

results matching ""

    No results matching ""