리덕스란?
리덕스란 무엇이고 왜 사용하는 것인지 알아보자.
리덕스는 사실 알고나면, 정해진 구조를 배신하지 않는 형태이고 단방향으로 데이터를 제어하기 때문에 전혀 어렵지 않다.
리덕스를 배우기 전에: '상태' 란?
리덕스를 공부하다보면 '상태' 란 말을 많이 사용한다. 여기서 말하는 '상태' 란, 간단히 '변수'라고 생각해도 된다. '상태'는 보통 리액트와 같은 SPA 프레임워크에서 UI 가 변하는 기준점이 되는 변수를 말한다.
리덕스는 보통 '상태 관리' 라이브러리라고 불리우며, 리액트 앱의 전역에서 사용되는 '상태' 를 관리할 때 주로 사용된다.
예측 가능한 앱 작성을 도와준다.
리덕스로 만든 앱은...
- 일관성 있게 동작한다.
- 여러 환경 (클라이언트, 서버, 네이티브) 에서 동작 가능하다.
- 애플리케이션이 테스트하기 쉬워진다.
중앙화를 도와준다.
로직과 상태를 중앙화 시킨다는 것은 앱에서 실행취소/되돌리기 및 상태 보존 과 같은 강력한 능력을 준다.
앱 디버깅이 가능하도록 도와준다.
리덕스는 애플리케이션 내부에서 다루는 '상태'가 언제, 어디서, 왜, 어떻게 변화하였는지 추적하기 쉽게 만들어준다.
리덕스 아키텍처는 변화를 기록하기 쉬운 형태로 설계되어 있어 시간 여행 디버깅 이 가능하다. 심지어 서버로 완전한 에러 리포트를 보내는 것도 가능하다.
유연하다.
리덕스는 UI 레이어와 함께 동작한다. 필요 요구사항에 맞는 커다란 확장프로그램 에코 시스템도 가지고 있다.
용량이 작다
2kb 의 작은 용량으로 위와 같은 기능을 제공한다.
리덕스 핵심 개념 알아보기
리덕스의 핵심 개념은 '상태' 와 '액션' 으로 설명될 수 있다.
아주 간단히 요약하자면, 리덕스는 '상태' 를 관리하고 있고, 이는 '액션' 에 의해서만 변한다.
'액션'이 구체적으로 어떻게 구현되는지는 '리듀서' 가 결정한다.
리덕스는 '상태(State)' 를 가지고 있다.
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
상태란 순수한 자바스크립트 오브젝트이다. 이 자바스크립트 오브젝트는 일반적인 자바스크립트 코드로는 절대 내부의 값을 변경할 수 없다.
오직 리덕스의 '액션' 이라는 것을 통해 값을 바꿀 수 있다.
리덕스의 '액션(Action)' 은 '상태(State)' 를 변화시킨다.
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
위는 몇가지 액션의 예이다.
- 어떤 타입의 액션인지 어떤 값을 넘기는지 알 수 있다.
- 오직 '액션' 을 통해 상태가 변경되므로 추적이 용이하다.
- 언제, 어디서, 어떤 액션을 수행했는지 추적 가능하다.
리덕스(Redux) 는 '리듀서(Reducer)' 라는 것을 통해 액션별 행위를 구체적으로 정의할 수 있다.
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action),
};
}
function visibilityFilter(state = "SHOW_ALL", action) {
if (action.type === "SET_VISIBILITY_FILTER") {
return action.filter;
} else {
return state;
}
}
function todos(state = [], action) {
switch (action.type) {
case "ADD_TODO":
return state.concat([{ text: action.text, completed: false }]);
case "TOGGLE_TODO":
return state.map((todo, index) =>
action.index === index
? { text: todo.text, completed: !todo.completed }
: todo
);
default:
return state;
}
}
위의 코드는 실제로 ADD_TODO
, SET_VISIBILITY_FILTER
등의 액션이 구체적으로 상태에 어떤 영향을 미치는지 정의한 것이다.
이를테면 ADD_TODO
의 행위는 text
인자로 넘어온 문자열이 포함된 새로운 오브젝트를 상태에 추가시킨다.
리듀서로 { type: 'ADD_TODO', text: 'Go to swimming pool' }
와 같은 액션이 들어왔다면, state
의 상태는 다음과 같이 변할 수 있다.
리듀서와 액션은 실제로 1:1로 짝을 이룬다.
리덕스의 dispatch()
는 액션 (Action)
을 실제로 실행시킨다.
코드상에서 dispatch()
를 통해 액션이 실행되고, 아래에서 등장하는 리듀서(Reducer) 에 있는 구체적 행위가 실행된다. 반면, 행위가 정의되어 있어도 dispatch()
가 없다면, 아무런 동작을 하지 않을 것이다.
리듀서 (Reducer) 내부의 작은 조각들 슬라이스 (Slice)
슬라이스는 한 리듀서 내부에 너무 많은 상태에 대한 데이터가 들어가지 않도록 쪼개주는 단위이다.
위에서 todos
와 visibilityFilter
와 같이 상태의 프로퍼티 별로 초기값, 액션 등을 나누어 정의한 것이 슬라이스 개념이라고 볼 수 있다.
슬라이스를 각각 다른 파일로 나누는 경우도 있으니, 나중에 이런 형식으로 작성된 프로젝트 구조를 보아도 놀라지 말자.
엑스트라 리듀서 (Extra Reducer): 비동기적인 리듀서
리듀서의 행위를 비동기적으로 정의할 때는 Extra Reducer 라는 용어를 이용하니 참고해두자.
액션 적용 전, 후 예제 데이터
액션 적용 전
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
액션 적용 후
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}, {
text: 'Go to swimming pool',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
자바스크립트의
Array.prototype.concat()
함수는 원본 배열을 변화시키지 않으면서도, 인자로 온 원소가 더해진 배열을 반환한다는 점을 생각하면 쉽게 이해할 수 있다.
레퍼런스
'자바스크립트 > 라이브러리' 카테고리의 다른 글
아이언 세션 (Iron session) 이란 무엇인가? (쉬운 설명과 보안 관련 생각해볼점) (0) | 2024.04.03 |
---|---|
자바스크립트의 Socket.io 라이브러리란? (웹소켓 통신 라이브러리) (0) | 2024.02.10 |
자바스크립트 라이브러리 Axios 란? (0) | 2022.10.19 |
Socket.io 소켓 IO 란? (0) | 2022.10.15 |
리덕스 툴킷 (Redux toolkit) 이란? (0) | 2022.10.13 |