React를 다루는 기술 16 - Redux 라이브러리 이해하기
Redux
Redux 라이브러리는 가장 많이 사용하는 리액트 상태 관리 라이브러리이다.
Redux를 사용했을 경우의 장점은
- 컴포넌트의 상태관리로직을 다른 파일로 분리시킬 수 있다.
- 컴포넌트끼리 똑같은 상태를 공유해야 할 때 여러 컴포넌트를 거치지 않고 손쉽게 전달하거나 업데이트 할 수 있다.
등이 있다.
리액트 버전 16.3 전까지는 Context API를 사용하기 위한 사전작업이 필요했기 때문에 상태관리를 위해서는 Redux를 대부분 사용했지만 이후 Context API를 사용하기 편해지면서 간단한 관리라면 Context API가 더 유용해졌다.
하지만 프로젝트가 복잡도를 더해갈수록 Redux 라이브러리가 가진 이점이 커지고 추가로 편리한 개발자 도구와 미들웨어라는 기능을 지원하기 때문에 Redux를 사용하는 쪽을 추천한다.
Redux를 이해하기 위해선 몇 가지 개념을 이해해야 하는데 그 개념은 이하와 같다.
1] 액션
상태에 변화가 필요할 경우 액션(action)이라는 것이 발생하는데 이는 하나의 객체로 이루어져있다.
{
type: 'TOGGLE_VALUE';
}
액션객체는 반드시 type를 가지고 있어야하는데 이 type에 담긴 값이 액션의 이름, 키와 같은 역할을 하기 때문이다.
그 외에는 작성자가 마음대로 값을 추가할 수 있다.
{
type: 'ADD_TODO',
data: {
id: 1,
text: '리덕스 배우기'
}
}
2] 액션 생성 함수
액션 생성 함수(action creator)는 액션 객체를 만들어주는 함수이다.
function addTodo(data) {
return {
type: 'ADD_TODO',
data
}
}
어떠한 변화를 일으키기 위해서는 액션 객체를 생성해야하는데 매번 액션 객체를 직접 생성하기에는 번거롭고 작성 중 실수. 특히 type명을 잘못 작성할 수도 있기 때문에 액션 생성 함수를 만들어 사용한다.
3] 리듀서
리듀서(reducer)는 변화를 발생시키는 함수이다.
액션을 만들어서 발생시키면 리듀서가 현재 상태와 전달받은 액션 객체를 비교하여 새로운 상태를 생성하여 반환해준다.
const initialState = {
counter: 1
}
function reducer(state = initialState, action) {
switch (action.type) {
case INCREMENT:
return (
counter: state.counter + 1
)
default:
return state;
}
}
4] 스토어
프로젝트에 리덕스를 적용하기 위하여 스토어(store)를 만든다.
한 개의 프로젝트에는 한 개의 스토어만 존재해야하며 스토어 안에는 어플리케이션의 상태와 리듀서가 존재한다.
5] 디스패치
디스패치(dispatch)는 스토어의 내장 함수 중 하나로 액션을 발생시키는 역할을 한다.
dispatch(action)
과 같은 형태로 액션 객체를 파라미터로 넣어 호출하며 이 함수가 호출되면 스토어는 리듀서 함수를 통해 새로운 상태를 생성한다.
6] 구독
구독(SubScribe)도 스토어의 내장 함수 중 하나로 subscribe함수 안에 리스너 함수를 파라미터로 넣어서 호출해주면 해당 리스너 함수가 액션이 디스패치되어 상태가 업데이트 될 때마다 호출된다.
const listener = () => {
console.log('상태가 업데이트 됨');
}
const unsubscribe = store.subscribe(listener);
unsubscribe(); // 추후 구독을 비활성화할 때 함수 호출
리덕스의 3가지 규칙
-
단일 스토어
하나의 어플리케이션 안에는 하나의 스토어만 들어있어야한다.
여러 개의 스토어를 사용하는 것도 가능은 하지만 상태관리가 복잡해질 수 있으므로 권장되지는 않는다. -
읽기 전용 상태
리덕스 상태(state)는 읽기 전용이다.
기존의 컴포넌트에서 state를 변경할 때 setState 혹은 useState에서 반환해주는 업데이트 함수를 사용하는 과정에서 불변성을 지켜주기 위해 spread 연산자를 사용하거나 immer와 같은 불변성 관리 라이브러리를 사용하는 등 불변성을 유지하는 것이 아주 중요했다.
리덕스에서도 마찬가지로 불변성을 유지해줘야하는데 이는 내부적으로 데이터가 변경되는 것을 감지할 때 얕은 복사를 통해 비교하기 때문이다.
때문에 불변성을 유지해야 좋은 성능을 유지할 수 있다. -
리듀서는 순수함수
리듀서는 순수함수여야하며 때문에 아래와 같은 조건을 지켜야한다.
- 리듀서 함수는 이전 상태와 액션 객체를 파라미터로 받는다.
- 파라미터 외의 값에 의존해서는 안된다.
- 이전 상태는 절대 건드리지 않고 변화를 준 새 상태 객체를 만들어서 반환해야한다.
- 똑같은 파라미터로 호출된 리듀서 함수는 항상 똑같은 결과값을 반환해야한다.
리듀서 함수는 외부의 값에 의존하거나 호출할 때마다 동일한 파라미터여도 다른 결과가 나와서는 안된다.
즉, 내부에서 Date 함수 등으로 실시간 정보를 가져오거나 ajax 통신을 이용하여 외부의 값을 가져오는 등의 기능은 사용해서는 안된다.
출처자료
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=209354690 (리액트를 다루는 기술(개정판))