초깃값 설정
프로젝트에서 사용할 초깃값을 정의합니다.
초깃값의 형태는 숫자, 문자열, 객체 등 자유롭게 설정합니다.
- index.js
const divToggle = document.querySelector(".toggle");
const counter = document.querySelector("h1");
const btnIncrease = document.querySelector("#increase");
const btnDecrease = document.querySelector("#dncrease");
const TOGGLE_SWITCH = "TOGGLE_SWITCH";
const INCREASE = "INCREASE";
const DECREASE = "DECREASE";
const toggleSwitch = () => ({ type: TOGGLE_SWITCH });
const increase = (difference) => ({ type: INCREASE, difference });
const decrease = () => ({ type: DECREASE });
const initalState = {
toggle: false,
counter: 0
};
리듀서 함수 정의
리듀서는 변화를 일으키는 함수입니다.
함수의 파라미터로 state, action 값을 받아와서 설정합니다.
- index.js
리듀서 함수가 처음 호출될 떄는 state 값이 undefined 입니다.
값이 undefined로 주어질 떄 inititalState 값을 기본 값으로 설정합니다.
리듀서에서는 상태의 불변성을 유지하면서 데이터 변화(action)을 발생시켜야합니다.
이 작업은 spread 연산자(...state)를 사용하면 쉽게 작업 할 수 있습니다.
객체의 구조가 복잡해지거나 배열도 함께 다루는 경우 immer 라이브러리를 사용하면 조금 더 쉽게 리듀서를 작성 할 수 있습니다.
const divToggle = document.querySelector(".toggle");
const counter = document.querySelector("h1");
const btnIncrease = document.querySelector("#increase");
const btnDecrease = document.querySelector("#dncrease");
const TOGGLE_SWITCH = "TOGGLE_SWITCH";
const INCREASE = "INCREASE";
const DECREASE = "DECREASE";
const toggleSwitch = () => ({ type: TOGGLE_SWITCH });
const increase = (difference) => ({ type: INCREASE, difference });
const decrease = () => ({ type: DECREASE });
const initalState = {
toggle: false,
counter: 0,
};
// state 값이 undefined 일떄 initalState 기본값 사용
function reducer(state = initalState, 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;
}
}
스토어 만들기
이제 스토어를 추가 해 보겠습니다.
스토어를 만들 떄 createStore 함수를 선언합니다.
이 함수를 사용하면 코드 안에 import를 사용해서 createStore 함수를 불러와야 하고 함수의 파라미터를 리듀서에 넣어주어야 합니다.
- index.js
import { createStore } from "redux";
(...)
// store 안에 reduer 함수 추가
const store = createStore(reducer);
render 함수 만들기
이번에는 render 함수를 작성 하겠습니다.
이 함수는 상태가 업데이트 되면 호출합니다.
리엑트의 render 함수에는 다르게 이미 html을 사용합니다.
- index.js
import { createStore } from "redux";
(...)
// store 안에 reduer 함수 추가
const store = createStore(reducer);
const render = () => {
const state = state.getState(); // 현재 상태 불러오기
// 토글 분기처리
if (state.toggle) {
divToggle.classList.add("active");
} else {
divToggle.classList.remove("active");
}
// 카운터 처리
counter.innerText = state.counter;
};
render();
구독하기
이번에는 스토어의 상태가 바뀔 때마다 작성한 render 함수가 호출되도록 해 줄 것입니다.
이작업은 스토어의 subscribe 함수를 사용하여 처리합니다.
subscribe 함수의 파라미터로 함수 형태의 값을 전달해 줍니다.
이렇게 전달된 함수는 action이 발생하여 상태가 업데이트되면 호출됩니다.
- index.js
이번에는 subscribe 함수를 사용했지만.
리엑트 프로젝트에서는 react-redux 라이브러리가 작업을 대신해주기 때문에 필요가 없습니다.
이제 상태이트가 업데이트될 때마다 render 함수를 호출하도록 합니다.
import { createStore } from "redux";
(...)
// store 안에 reduer 함수 추가
const store = createStore(reducer);
const render = () => {
const state = state.getState(); // 현재 상태 불러오기
// 토글 분기처리
if (state.toggle) {
divToggle.classList.add("active");
} else {
divToggle.classList.remove("active");
}
// 카운터 처리
counter.innerText = state.counter;
};
render();
store.subscribe(render);
액션 발생시키기
액션을 발생시키는 것을 디스패치(dispatch)라고 합니다.
디스패치를 할 때는 스토어의 내장 함수 dispatch를 사용하여 처리합니다.
- index.js
import { createStore } from "redux";
(...)
// store 안에 reduer 함수 추가
const store = createStore(reducer);
const render = () => {
const state = state.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(toggleSwitch());
};
btnIncrease.onclick = () => {
store.dispatch(increase(1));
};
btnDecrease.onclick = () => {
store.dispatch(decrease());
};
최종 결과
- 원 마우스 클릭 시 toggle 클래스 active로 변경 (컬러 변경)
- 원 다시 클릭 시 toggle 클래스 active 삭제
- +1, -1 버튼 클릭 시 state 값 증가 또는 감소
최종 소스
'프론트엔드 > React' 카테고리의 다른 글
[프론트엔드] 리덕스를 사용하여 리액트 어플리케이션 상태 관리하기[1] (0) | 2022.04.06 |
---|---|
[프론트엔드] REACT Redux 라이브러리[5] (0) | 2022.04.06 |
[프론트엔드] REACT Redux 라이브러리[3] (0) | 2022.04.05 |
[프론트엔드] REACT Redux 라이브러리[2] (0) | 2022.04.04 |
[프론트엔드] REACT Redux 라이브러리[1] (0) | 2022.04.03 |