티스토리 뷰

html파일에서 간단하게 증감버튼을 만들고, JavaScript파일로 DOM조작을 하고, Redux로 상태를 관리한다.

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="add">add</button>
    <span></span>
    <button id="minus">minus</button>
    <!-- redux script -->
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.1/redux.min.js"
      integrity="sha512-1/8Tj23BRrWnKZXeBruk6wTnsMJbi/lJsk9bsRgVwb6j5q39n0A00gFjbCTaDo5l5XrPVv4DZXftrJExhRF/Ug=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    ></script>
    <!-- JS script -->
    <script src="index.js"></script>
  </body>
</html>

DOM조작을 위해 브라우저 환경에서 작업하였다. 리액트를 주로 사용했어서 자연스럽게 npm install redux를 하고, commonJS 또는 모듈import/export로 createStore메서드를 가져와서 사용하려니 불가능했다. 이는 node.js 환경에서 가능한 것인데 말이다.
(브라우저 환경이 아닌 node.js 환경에서 웹 어플리케이션을 만드려면 다양한 node.js 패키지들을 설치하고 세팅해주어야 한다. 그렇기 때문에 이러한 것들을 미리 설치하고 세팅해놓은 보일러 플레이트 CRA를 이용해서 리액트 앱을 시작하는 것이다.)

redux를 브라우저 환경에서 사용하기 위해 html파일에 cdn script를 추가하여 redux를 사용한다.
https://cdnjs.com/libraries/redux 에서 찾을 수 있다.

 

store를 생성한다.

// index.js
const reducer = () => {};
const store = Redux.createStore(reducer);

store 내부

익명의 함수 reducer를 만들고 createStore메서드로 store를 생성한 뒤 콘솔에서 확인해보면, store은 dispatch, getState, subscribe 등의 함수를 가지고 있는 것을 볼 수 있다. 리액트에서는 Hooks를 사용했지만 바닐라 자바스크립트에서는 이 세 가지 함수를 주로 사용한다.

 

reducer를 완성한다.

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

 


dispatch 함수로 action 객체를 reducer 함수에게 전달한다.

action은 동일하게 action 생성자를 사용하거나, 직접 action 객체를 전달한다.
이번에는 action 생성자를 사용하지 않고 직접 전달해주었다.
위에서 보았듯이 store 가 제공하는 dispatch 메서드를 사용한다.

또한 getState 메서드를 사용하면 현재 상태값을 가져온다. 리액트 Hooks의 useSelector와 비슷하다고 보면 된다.
html에서 처음에 상태의 초기값인 0을 렌더링하기 위해 number의 innerText에 getState 메서드로 할당해준다. 

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

const onAddClick = () => {
  store.dispatch({ type: "ADD" });
};

const onMinusClick = () => {
  store.dispatch({ type: "MINUS" });
};

number.innerText = store.getState();
add.addEventListener("click", onAddClick);
minus.addEventListener("click", onMinusClick);

 

상태변화를 감지한다.

리액트가 아니기 때문에 상태가 변한다고 자동으로 리렌더링이 일어나지 않는다. 상태가 변하기만 할 뿐이고, DOM이 변형되어야 리렌더링이 일어난다. 먼저 상태가 변하는 것을 추적하는 subscribe 메서드를 사용하여, 상태가 변할 때마다 DOM을 조작하도록 한다.
subscribe 메서드는 상태 갱신이 일어날 때마다 실행할 콜백함수(onChange)를 전달인자로 받는다.

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

store.subscribe(onChange);

 

전체 코드

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

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

const store = Redux.createStore(reducer);

const onAddClick = () => {
  store.dispatch({ type: "ADD" });
};

const onMinusClick = () => {
  store.dispatch({ type: "MINUS" });
};

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

store.subscribe(onChange);

number.innerText = store.getState();
add.addEventListener("click", onAddClick);
minus.addEventListener("click", onMinusClick);

 

Redux를 리액트에서 사용하는 방법은 다음의 포스팅에 다루었다.

 

Redux란 / Redux React에서 사용하기

Redux는 JavaScript 어플리케이션의 상태를 관리할 수 있는 상태 관리 라이브러리이다.(React, Vue, Angular, vanilla JS 등 모두 사용할 수 있다.) React로 상태 관리를 할 때 props drilling이나 상태끌어올리기를

hahagarden.tistory.com

 

 

반응형
댓글