Redux_(2) 바닐라 자바스크립트로 리덕스 구현하기

임쿠쿠·2020년 11월 11일
0

리덕스

목록 보기
2/3
post-thumbnail

바닐라 자바스크립트 환경에서 리덕스사용

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body>
    <div class="toggle"></div>
    <hr />
    <h1>0</h1>
    <button id="increase">+1</button>
    <button id="decrease">-1</button>
    <script src='./index.js'></script>
</body>
</html>

index.css

.toggle {
  border: 2px solid black;
  width: 64px;
  height: 64px;
  border-radius: 32px;
  box-sizing: border-box;
}

.toggle.active {
  background: yellow;
}

index.js

import { createStore } from "redux";

const divToggle = document.querySelector(".toggle");
const counter = document.querySelector("h1");
const btnIncrease = document.querySelector("#increase");
const btnDecrease = document.querySelector("#decrease");

1. 액션 타입과 액션 생성 함수 정의

(...)
 
// 프로젝트의 상태에 변화를 일으키는 것을 액션이라 하고, 액션에 이름을 정의한다.
// 액션 이름은 문자열 형태로, 주로 대문자로 작성하며 액션 이름은 고유해야 한다.
const TOGGLE_SWITCH = "TOGGLE_SWITCH";
const INCREASE = "INCREASE";
const DECREASE = "DECREASE";
 
//다음으로 이 액션 이름을 사용하여 액션 객체를 만드는 액션 생성 함수 작성
//액션 객체는 type 값을 반드시 갖고 있어야 한다.
//increase의 경우 difference 파라미터에 원하는 값을 추 후 적용
const toggleSwitch = () => ({ type: TOGGLE_SWITCH });
const increase = (difference) => ({ type: INCREASE, difference });
const decrease = () => ({ type: DECREASE });

2. 초깃값 설정

(...)
 
const initialState = {
  toggle: false,
  counter: 0,
};

3. 리듀서 함수 정의

(...)
 
// 리듀서는 변화를 일으키는 함수이다. 함수의 파라미터로는 state와 action 값을 받아 온다.
// state가 undefined일 때는 initialState를 기본값으로 사용
function reducer(state = initialState, action) {
  //action.type에 따라 다른 작업을 처리함
  switch (action.type) {
    case TOGGLE_SWITCH:
      return {
        ...state,
        toggle: !state.toggle,
      };
    case INCREASE:
      return {
        ...state,
        counter: state.counter + action.difference,
      };
    case DECREASE:
      return {
        ...state,
        counter: state.counter - 1,
      };
    default:
      return state;
  }
}
//리듀서에서는 상태의 불변성을 유지하면서 데이터에 변화를 일으켜 주어야 한다. 이 작업을 할 때 spread 연산자를 사용하면 편하다.

4. 스토어 만들기

(...)
 
const store = createStore(reducer);

5. render 함수 만들기

(...)
 
//render 함수는 상태가 업데이트될 때마다 호출되며, 리액트의 render 함수와는 다르게 이미 html을 사용하여 만들어진 UI의 속성을 상태에 따라 변경해준다.

const render = () => {
  const state = store.getState(); // 현재 상태를 불러온다.
  // 토글 처리
  if (state.toggle) {
    divToggle.classList.add("active");
  } else {
    divToggle.classList.remove("active");
  }
  // 카운터 처리
  counter.innerText = state.counter;
};

render();

6. 구독하기

(...)
 
//이제 스토어의 상태가 바뀔 때마다 방금 만든 render함수가 호출되도록 해준다. 이 작업은 스토어의 내장 함수 subscribe를 사용하여 수행할 수 있다.
//subscribe 함수의 파라미터로는 함수 형태의 값을 전달해 준다 이렇게 전달된 함수는 추후 액션이 발생하여 상태가 업데이트될 때마다 호출된다.

store.subscribe(render);

7. 액션 발생시키기

(...)
 
//액션을 발생시키는 것을 디스패치라고 한다. 디스패치를 할 때는 스토어의 내장 함수 dispatch를 사용한다. 파라미터는 액션 객체를 넣어 주면 된다.
//다음과 같이 각 DOM 요소에 클릭 이벤트를 설정하여 이벤트 함수 내부에서는 dispatch 함수를 사용하여 액션을 스토어에게 전달한다.

divToggle.onclick = () => {
  store.dispatch(toggleSwitch());
};
btnIncrease.onclick = () => {
  store.dispatch(increase(2));
};
btnDecrease.onclick = () => {
  store.dispatch(decrease());
};

참고 - 리액트를 다루는 기술(김민준)

profile
Pay it forward

0개의 댓글