#1. Vanilla JS + Redux로 Counter App 만들기

마리 Mari·2021년 6월 28일
0

Goal

  • Add 버튼 클릭 시 화면의 숫자의 값이 +1
  • Minus 버튼 클릭 시 화면의 숫자의 값이 -1


App without Redux

index.html

<body>
    <button id="add">Add</button>
    <span>0</span>
    <button id="minus">Minus</button>
  </body>

index.js

const add = document.getElementById("add");
const minus = document.getElementById("minus");
const number = document.querySelector("span");

let count = 0;
number.innerText = count;

const updateText = () => {
    number.innerText = count;
}

const handleAdd = () => {
    count = count + 1;
    updateText();
}
const handleMinus = () => {
    count = count - 1;
    updateText();
}

add.addEventListener("click", handleAdd);
minus.addEventListener("click", handleMinus);

Handle 함수에서 update 함수를 호출하여 값이 바뀌었다는 것을 알려주어야 한다.




App with Redux

1. redux 설치

yarn add redux

npm install redux

2. create store , add reducer(modifier)

import { createStore } from "redux";

const countModifier = (state = defaultValue) => {
	// ... modifying state
	return state; // modified state
};
const countStore = createStore(countModifier);

store ?

: 하나의 데이터(state)를 저장하는 공간

  • state ⇒ application 안에서 변하는 data
    • 위의 app에서는 count가 state가 된다.
  • reducer라는 함수를 인자로 요구한다.

reducer ?

: state를 변화시킬 수 있는 유일한 함수

  • modifier라고도 불리며, modifier가 반환하는 값이 state의 값이 된다.
  • 인자로 기존 state를 받으며, 바뀐 state를 반환한다.
  • default 값을 설정해야 한다. (안하면 undefined)

store 의 Methods

  • dispatch, getState, subscribe, replaceReducer로 총 4개
  • getState() 로 state의 값을 가져올 수 있다.

3. action으로 state의 변경 방법 설정

const countModifier = (count = 0, action) => {
    if (action.type == "ADD") {
        return count + 1;
    } else if (action.type == "MINUS") {
        return count - 1;
    } else {
        return count;
    }
};
const countStore = createStore(countModifier);

countStore.dispatch({ type: "ADD" });

action ?

  • modifier와 소통하는 방법으로, modifier의 두번째 인자로 들어간다.
  • store의 method인 dispatch 를 이용해 action이 적용된 modifier를 호출한다.

dispatch ?

  • object { type: "actionName" } 을 인자로 받는다.

  • store.dispatch({ type : "action1" }) 이 호출되면

    store.modifier( state, action: { type : "action1" } ) 이 실행됨.


4. subscribe으로 store의 변화 감지하고, 감지 시 html 변경 하기

...
const onChange = () => number.innerText = countStore.getState();
countStore.subscribe(onChange);

const handleAdd = () => countStore.dispatch({ type: "ADD" });
const handleMinus = () => countStore.dispatch({ type: "MINUS" });

add.addEventListener("click", handleAdd);
minus.addEventListener("click", handleMinus);

subscribe ?

: store안의 변화를 감지하고, 감지되었을 때 인자로 받은 함수를 실행한다.


5. Refactor

  • modifier 의 action을 switch문을 이용하여 풀기. (일반적인 패턴)
const countModifier = (count = 0, action) => {
    switch (action.type) {
        case "ADD":
            return count + 1;
        case "MINUS":
            return count - 1;
        default:
            return count;
    }
};
  • action.type을 string이 아닌 string이 할당된 변수로 입력
    • string으로 바로 입력시 실수할 가능성이 있음.
    • 디버깅이 용이해짐
const ADD = "ADD";
const MINUS = "MINUS";

const countModifier = (count = 0, action) => {
    switch (action.type) {
        case ADD:
            return count + 1;
        case MINUS:
            return count - 1;
        default:
            return count;
    }
};

// ...

const handleAdd = () => countStore.dispatch({ type: ADD });
const handleMinus = () => countStore.dispatch({ type: MINUS });

전체 코드

import { createStore } from "redux";

const add = document.getElementById("add");
const minus = document.getElementById("minus");
const number = document.querySelector("span");

number.innerText = 0;

const ADD = "ADD";
const MINUS = "MINUS";

const countModifier = (count = 0, action) => {
    switch (action.type) {
        case ADD:
            return count + 1;
        case MINUS:
            return count - 1;
        default:
            return count;
    }
};
const countStore = createStore(countModifier);

const onChange = () => number.innerText = countStore.getState();
countStore.subscribe(onChange);

const handleAdd = () => countStore.dispatch({ type: ADD });
const handleMinus = () => countStore.dispatch({ type: MINUS });

add.addEventListener("click", handleAdd);
minus.addEventListener("click", handleMinus);
profile
우리 블로그 정상영업합니다.

0개의 댓글