
전역 상태를 관리 할때 효율적이다
상태에 어떠한 변화가 필요하면 액션이 발생한다, (똥마렵다 → 똥을 싼다!)
{
type: 'TOGGLE_VALUE'
}
{
type: 'ADD_TODO',
data:{
id: 1 ,
text: '리억스 배우기'
}
}
{
type:'CHANGE_INPUT',
text:'안녕하세요'
}
액션 객체를 만들어 주는 함수
funtion addTodo(data){
return{
type: 'ADD_TODO',
data
};
}
// 화살표 함수로도 가능하다
const changeInput = text => ({
type: 'CHANGE_INPUT',
text
});
변화를 일으키는 함수
// 전역 상태
const initialState = {
counter: 1
};
// 상태, 액션 객체
function reducer(state = initialState, action) {
switch (action.type) {
case INCREMENT:
return {
counter: state.counter + 1
};
default:
return state;
}
}
// 디스패치
... 생략 dispatch({ type: 'INCREMENT' }) // 액션 객체를 리듀서로 보내는 함수
리덕스를 적용하기 위해 사용됨
액션 객체를 파라미터로 넣어서 호출 ⇒ 리듀서 함수를 실행시켜 새로운 상태를 만든다
subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출하면, 이 리스너 함수가 액션이 디스패치 되어 상태가 업데이트 될때 마다 호출 한다
const listener = () => {
console.log('상태가 업데이트됨');
}
const unsubscribe = store.subscribe(listener)
unsubscribe(); // 추후 구독을 비활성화 할때 함수 호출 -> 상태 업데이트 되도 호출 ㄴㄴ 함
바날리 자바스크립트로 리덕스 사용해보자
$ yarn global add parcel-bundler
$ mkdir vanilla-redux
$ cd vanilla-redux
# package.json 파일을 생성합니다.
$ yarn init -y
그러고 리덕스 모듈을 다운받아보자
$ yarn add redux
.toggle {
border: 2px solid black;
width: 64px;
height: 64px;
border-radius: 32px;
box-sizing: border-box;
}
.toggle.active {
background: yellow;
}
//
<html>
<head>
<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>
별도의 라이브러리를 사용하지 않기 때문에 직접 DOM에 접근해야함
const { createStore } = require("redux");
// DOM 래퍼런스 만들기
const divToggle = document.querySelector('.toggle');
const btnIncrease = document.querySelector('#increase');
const btnDecrease = document.querySelector('#decrease');
const counter = document.querySelector('h1');
// 액션 타입 정의
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 initialState = {
toggle: false,
counter: 0
};
// 리듀서 함수 정의
// 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;
}
}
// 스토어 만들기
const store = createStore(reducer)
//render함수 만들기
const render = () => {
const state = store.getState(); // 현재 상태를 불러옵니다.
// 토글 처리
if (state.toggle) {
divToggle.classList.add('active'); // 해당 클래스를 가진 클래스가 들어가면 css에 미리 설정된 값이 적용됨
} else {
divToggle.classList.remove('active');
}
// 카운터 처리
counter.innerText = state.counter; // counterDO에 현재 카운터의 상태를 넣는다
};
render();
// 구독하기
store.subscribe(render);
// 액션 발생시키기
divToggle.onclick = () => {
store.dispatch(toggleSwitch()); // store에 내장함수인 dispatch 이니깐
};
btnIncrease.onclick = () => {
store.dispatch(increase(1));
};
btnDecrease.onclick = () => {
store.dispatch(decrease());
};
하나의 애플리케이션 안에는 하나의 스토어
상태를 업데이트 할때 기존의 객체는 건드리지 않고 새로운 객체를 생성해주어야한다