리덕스 (Redux)
리덕스(Redux)
리덕스는 가장 사용률이 높은 상태관리 라이브러리로서, 리액트의 복잡한 컴포넌트 구조속에서 보다 간편하게 모든 컴포넌트들이 state를 쉽게 공유할 수 있게 해주는 방식이다. 리덕스는 리액트 내부에 있는 기술이 아니며 순수 HTML, JavaScript 내에서도 사용이 가능하다. 리액트와 시너지가 좋으니 대체적으로 리덕스를 사용할 뿐이다.
리덕스를 언제 써야 할까?
- 프로젝트의 규모가 큰가?
- Yes: 리덕스
- No: Context API
- 비동기 작업을 자주 하게 되는가?
- Yes: 리덕스
- No: Context API
- 리덕스를 배워보니까 사용하는 게 편한가?
- Yes: 리덕스
- No: Context API 또는 MobX
리덕스에서 자주 사용되는 키워드
액션(Action)
State에 어떤 변화가 필요할 때 우린 액션이란 것을 발생시키며 이는 하나의 객체이다.
단어 그대로 어떤 동작에 대해 선언되어진 객체이다.
액션은 반드시 type을 가지고 있어야 하고, 그 외의 값은 상황에 따라 넣어줄 수 있다.
// action 1
{
type: "NUMBER_COUNT"
},
// action 2
{
type: "CHANGE_INPUT",
text: "리덕수"
}
type은 쉽게 말해 어떤 동작인지를 표기한 지정표이다.
액션 생성 함수(Action Creator)
Action이 동작에 대해 선언된 객체면, Action Creator는 Action을 생성해 실제로 객체로 만들어주는 함수이다.
위 Action의 action 1은 아래와 같은 Action Creator를 통해 만들어진다.
export function numberCount(data) {
return {
type: "NUMBER_COUNT",
number: data
}
}
리듀서(Reducer)
State에 변화를 일으키는 함수이다. 위에 만들어진 Action 등의 일거리를 직접 수행하는 일을 한다.
리듀서는 현재의 State와 Action을 인자로 받아 Store(스토어)에 접근해 Action에 맞춰 State를 변경한다.
function reducer(state, action) {
switch(action.type) {
case 'NUMBER_COUNT':
return state + 1;
case 'CHANGE_INPUT':
return state;
default:
return state;
}
}
스토어(Store)
스토어는 현재 앱의 State와 Reducer함수, 그리고 몇 가지 내장 함수등을 갖고 있다.
스토어는 State를 수시로 확인해 View한테 변경된 사항을 알려주는 일을 한다.
디스패치(Dispatch)
디스패치는 스토어의 내장 함수 중 하나로 리듀서에게 Action을 발생하라고 시키는 것이라고 이해하면 된다.
dispatch 함수는 dispatch(action) 이런 식으로 Action을 인자로 넘긴다.
이렇게 호출하면 스토어가 리듀서 함수를 실행해, 리듀서 함수가 넘긴 액션을 처리해 새로운 상태를 만든다.
구독(Subscribe)
구독 또한 스토어의 내장 함수 중 하나로 함수 형태의 값을 인자로 받는데,
액션이 디스패치 될 때마다 전달해 준 함수를 호출한다.
=== 구독은 스토어를 주시하고 있다가 디스패치 될 때 함수를 호출한다.
리덕스의 3가지 규칙
- 하나의 애플리케이션 안에는 하나의 스토어만 가진다.
- 여러 개의 스토어를 사용하는 게 가능하나, 권장되지 않는다.
- 상태는 읽기 전용이다.
- 기존의 상태는 건드리지 않고 새로운 상태를 생성하여 업데이트해준다. 리덕스 고유의 불변성을 지켜야 한다.
- 변화를 일으키는 함수, 리듀서는 순수한 함수여야 한다.
- 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받는다.
- 이전의 상태는 절대로 건드리지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환한다.
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결괏값을 반환해야 한다.
new Date(), 랜덤 숫자 생성, 네트워크 요청등의 작업은 순수하지 않은 작업이므로, 리듀서 함수 바깥에서 처리해야 한다.