[React]리덕스(2) 흐름

2. 리액트 없이 리덕스 이용해보기

2.1. 초기 세팅

  • 바닐라 자바스크립트 이용
  • UI 관리하는 라이브러리를 이용하지 않기 때문에 DOM 직접 가리키는 값 선언해줌.

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="src/" />
    <meta charset="UTF-8" />
  </head>

  <body>
    <div class="toggle"></div>
    <hr />
    <h1>0</h1>
    <button id="increase">+1</button>
    <button id="decrease">-1</button>
    <script src="src/index.js"></script>
  </body>
</html>

styles.css

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

.toggle.active {
  background: yellow;
}

index.js

import "./styles.css";

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

2.2. 액션 타입과 액션 생성 함수 정의 및 초깃값 설정

  • 액션 이름 : 문자열, 대문자, 유일하게 존재
  • 액션 이름을 사용하여 액션 객체를 만드는 액션 생성함수를 만들었음.
import "./styles.css";

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

const TOGGLE_SWITCH = 'TOGGLE_SWITCH';
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE';
//액션

const toggle_switch = ()=>({type:TOGGLE_SWITCH});
const increase = difference=>({type:TOGGLE_SWITCH, difference});
const decrease = ()=>({type:DECREASE});
//액션 생성 함수

const initialState={
  toggle:false,
  counter:0
};
//초기값 설정

2.3. 리듀서 함수 정의

import "./styles.css";

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

const TOGGLE_SWITCH = "TOGGLE_SWITCH";
const INCREASE = "INCREASE";
const DECREASE = "DECREASE";
//액션 생성

const toggle_switch = () => ({ type: TOGGLE_SWITCH });
const increase = (difference) => ({ type: TOGGLE_SWITCH, difference });
const decrease = () => ({ type: DECREASE });
//액션 생성 함수 생성

const initialState = {
  toggle: false,
  counter: 0
};
//초기값 설정

function reducer(state = initialState, action) {
  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;
  }
}
  • reducer 함수가 맨 처음 호출될 때, state는 undefined : 이 경우에 initialState를 기본값으로 설정
  • 상태의 불변성 유지 : spread 연산자 사용

2.4. 스토어 생성

const store = createStore(reducer);
// 스토어 생성

2.5. 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();

//렌더함수 생성

2.6. 구독하기

  • 스토어 상태가 바뀔 때마다 render 호출되도록 해줌
  • 파라미터로 넘겨준 함수는 액션이 발생하여 상태가 업데이트될 때마다 호출됨
store.subscribe(render);
//구독

2.7. 액션 발생시키기

  • dispatch : 액션 발생
  • 각 DOM 요소에 클릭 이벤트 설정
  • 이벤트 내부에서는 dispatch를 이용하여 액션을 스토어에 전달
  • 액션 생성함수를 파라미터로 넘겨줌.
divToggle.onclick = () => {
  store.dispatch(toggle_switch());
};
btnIncrease.onclick = () => {
  store.dispatch(increase(1));
};
btnDecrease.onclick = () => {
  store.dispatch(decrease());
};
//액션 발생 
import { createStore } from "redux";
import "./styles.css";

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

const TOGGLE_SWITCH = "TOGGLE_SWITCH";
const INCREASE = "INCREASE";
const DECREASE = "DECREASE";
//액션 생성

const toggle_switch = () => ({ type: TOGGLE_SWITCH });
const increase = (difference) => ({ type: TOGGLE_SWITCH, difference });
const decrease = () => ({ type: DECREASE });
//액션 생성 함수 생성

const initialState = {
  toggle: false,
  counter: 0
};
//초기값 설정

function reducer(state = initialState, action) {
  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;
  }
}
//리듀서 함수 생성

const store = createStore(reducer);
// 스토어 생성

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

render();

//렌더함수 생성

store.subscribe(render);
//구독

divToggle.onclick = () => {
  store.dispatch(toggle_switch());
};
btnIncrease.onclick = () => {
  store.dispatch(increase(1));
};
btnDecrease.onclick = () => {
  store.dispatch(decrease());
};
//액션 발생 

좋은 웹페이지 즐겨찾기