전역 상태를 관리할 때 ContextAPI도 사용할 수 있지만, 리덕스를 사용하면 상태를 체계적으로 관리할 수 있다. 코드 유지 보수성, 작업 효율, 미들웨어 기능 제공을 통한 비동기 작업 관리 측면에서 좋다.
1. Action : 상태에 어떤 변화가 필요하면 발생한다.
- action 객체는 type 필드를 반드시 갖고 있어야 한다. (action의 이름과 같은 역할)
2. Action 생성 함수 : action 객체를 만들어 주는 함수이다. 어떤 변화를 일으켜야 할 때마다 액션 객체를 만들어야 한다.
function addTodo(data){
return {
type:'ADD_TODO',
data
};
}
3. Reducer : 변화를 일으키는 함수, 액션을 만들어서 발생시키면 reducer가 현재 상태와 전달받은 액션 객체를 파라미터로 받아온다. 그리고 두 값을 참고하여 새로운 상태를 만들어서 반환해준다.
cont initialState = {
counter: 1
};
function reducer(state = initialState, action){
switch(action.type){
case INCREMENT:
return {
counter: state.counter + 1
};
default:
return state;
}
}
4. Store : 한 개의 프로젝트는 하나의 스토어만 가질 수 있다. 스토어 안에는 현재 app 상태와 reducer가 들어가 있다.
- Dispatch : action을 발생시키는 것, action 객체를 파라미터로 넣어서 호출함. dispatch(action)
- Subscribe : listener 함수를 파라미터로 넣어서 호출해 주면, listener 함수가 action이 dispatch되어 상태가 업데이트 될 때마다 호출된다.
const listener = () => {
console.log('상태 업데이트');
}
const unsubscribe = store.subscribe(listner);
unsubscribe(); // 구독 비활성화
아래에서 확인해보자.
index.html
<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>
index.css
.toggle{
border: 2px solid black;
width: 64px;
height: 64px;
border-radius: 32px;
box-sizing: border-box;
}
.toggle.active{
background: yellow;
}
동그라미를 클릭하면 화면이 노란색으로 변하고 아래 버튼들을 클릭하면 숫자가 변한다.
index.js
1 ) Dom ref 생성
const divToggle = document.querySelector('.toggle');
const counter = document.querySelector('h1');
const btnIncrease = document.querySelector('#increase');
const btnDecrease = document.querySelector('#decrease');
2 ) Action Type 정의
const TOGGLE_SWITCH = 'TOGGLE_SWITCH';
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE';
3 ) Action 생성함수 정의
const toggleSwitch = () => ({ type: TOGGLE_SWITCH });
const increase = difference => ({type: INCREASE, difference});
const decrease = () => ({type: DECREASE});
4 ) 초기값, reducer 함수 설정
// 초깃값 설정
const initialState = {
toggle: false,
counter: 0
}
// reducer 함수 설정
function reducer(state = initialState, action){
// action.type에 따라 다른 작업을 처리함
switch(action.type){
case TOGGLE_SWITCH:
return{
...state, // 불변성 유지를 위해 spread 연산자 사용
toggle: !state.toggle
};
case INCREASE:
return{
...state,
counter: state.counter + action.difference
};
case DECREASE:
return{
...state,
counter: state.counter -1
};
default:
return state;
}
}
5 ) store를 생성하여 render함수 달아주기
// store 생성
const store = createStore(reducer);
// render 함수 만들기
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);
6 ) action 추가하기
// action 발생시키기
divToggle.onclick = () => {
store.dispatch(toggleSwitch());
};
btnIncrease.onclick = () => {
store.dispatch(increase(1));
};
btnDecrease.onclick = () => {
store.dispatch(decrease());
};
동그라미 버튼 클릭 -> onclick 이 발생하면서 store.dispatch로 action생성함수를 실행시키고 그 결과인 TOGGLE_SWITCH를 reducer에서 실행하게 된다. 이 때, state를 업데이트한다. 업데이트된 state는 render를 통해 UI에 반영된다.
'Programming > React.js' 카테고리의 다른 글
14. Redux로 React app 상태 관리 (0) | 2022.10.26 |
---|---|
12. ContextApi (0) | 2022.09.14 |
11. 라우터로 SPA 개발하기 (0) | 2022.09.08 |
10. immer사용하여 불변성 유지하기 (0) | 2022.08.31 |
9. 컴포넌트 성능 최적화 (0) | 2022.08.24 |