리덕스에 대해서 알아보기 전에 대략적인 개념을 알아보자.
파란색 블록이 녹색 블록의 정보를 수신하려면 녹색 블록 내부에 있어야 한다. 주황색 블록에서 녹색 블록 안에 있는 정보가 필요한 경우 검정색 블록으로 이동해야 한다.
이처럼 블록에 다른 구성요소가 있는 정보가 필요한 경우 이 정보를 두 구성 요소에 공통적인 상위 구성 요소로 이동해야 하기 때문에 문제가 있었다.
복잡하고 큰 응용 프로그램이 있고 최상위 구성 요소에서 최하위 구성 요소로 데이터를 전달해야 한다고 생각해보자. 아마도 매우 복잡한 코드를 작성하게 될 것이다.(A 컴포넌트가 G 컴포넌트에 접근해 무언가 하려고 한다면 A ▶ B ▶ C ▶ D ▶ E ▶ F ▶ G 순서로 접근 후, 다시 G ▶ F ▶ E ▶ D ▶ C ▶ B ▶ A 루트를 통해 돌아와야한다.)
이 때 하나의 Store라는 매체를 두면 A ▶ Store ▶ G 식의 효율적인 접근이 가능하게 해준다. 이 Store는 Redux를 통해 사용할 수 있다.
Redux(리덕스) 란?
리덕스는 애플리케이션의 상태를 관리하기 위한 라이브러리이다.
리액트의 복잡한 컴포넌트 구조속에서 보다 간편하게 모든 컴포넌트들이 state를 공유할 수 있게 해준다. 리덕스는 리액트 내부에 있는 기술이 아니며 Vue, HTML, JAVASCRIPT 내에서도 사용 가능하다.
Redux Terms
- State는 애플리케이션의 일부를 설명하는 개체이다.
- View는 State에 따라 조정될 것이다.
- Action은 State를 바꾼다.
- View로 돌아가서 Action이 State를 변경하면, View는 다시 랜더링된다.
Redux 개념
Action
Action은 State에 어떤 변화가 필요할 때 Action을 발생시키며 이는 하나의 객체이다.
Action은 애플리케이션에서 Store로 데이터를 설명하고 전송하는 payload이다. 반드시 type 필드를 가지고 있어야 하며, 그 외의 값은 상황에 따라 넣어줄 수 있다.
Action Creator
Action이 동작에 대해 선언된 객체라면, Action Creator는 Action을 생성해 객체로 만들어주는 함수이다.
const addTodo = text => {
return {
type: 'todos/addTodo',
payload: text
}
}
Reducer
Reducer는 애플리케이션의 상태가 어떻게 변경되고 새 상태를 반환하는지 지정하는 순수 함수이다. 리듀서는 기존 상태를 수정할 수 없으며 상태는 새 상태를 기반으로 하고 비동기 논리를 수행하지 않으며 Datatime과 같은 객체를 저장하지 않는다.
쉽게 말하면 만들어진 Action 등의 일거리를 직접 수행하는 역할을 한다. Reducer는 State와 Action을 인자로 받아 Store에 접근해 Action에 맞춰 State를 변경한다.
const todoReducer= (state = {}, action) => {
switch (action.type) {
case "todos/addTodo":
return {
...state,
...action.payload
};
default:
return state;
}
};
Store
Store는 현재 애플리케이션의 State와 Reducer 함수, 그리고 몇 가지 내장 함수 등을 가지고 있다. 수시로 State를 확인해서 View에 변경된 사항을 알려준다고 생각하면 된다.
const store = createStore(todoReducer);
Dispatch
Dicpatch는 Store의 내장 함수 중 하나로 Reducer에게 Action을 발생시키는 것이다.
Dicpatch 함수는 Action을 인자로 넘겨, 호출을 하면 Store가 Reducer 함수를 실행해 Reducer 함수가 넘긴 액션을 처리해 새로운 State를 만들어 준다.
store.dispatch(addTodo("Todo"))
Subscribe
Subscribe도 Store의 내장 함수 중 하나이다. Subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출해 주면, 이 리스너 함수가 액션이 디스패치되어 상태가 업데이트될 때마다 호출 된다.
const listener = () => {
console.log('상태가 업데이트 됨');
}
const unsubscribe = store.subscribe(listener);
unsubscribe();
Redux의 세 가지 규칙
- 단일 스토어
- 하나의 어플리케이션 안에는 하나의 스토어가 들어 있다. 여러 개의 스토어를 사용하는 것이 완전히 불가능하지는 않지만 특정 업데이트가 너무 빈번하게 일어나거나 애플리케이션의 특정 부분을 완전히 분리시킬 때 여러 개의 스토어를 만들 수도 있지만, 상태관리가 복잡해질 수 있으므로 권장하지 않는다.
- 읽기 전용 상태
- Redux 상태는 읽기 전용이다. 기존에 리액트에서 setState를 사용하여 state를 업데이트할 때도 객체나 배열을 업데이트하는 과정에서 불변성을 지켜 주기 위해 spread 연산자를 사용하거나 immer와 같은 불변성 관리 라이브러리를 사용한 것처럼 Redux도 마찬가지이다. 상태를 업데이트할 때 기존의 객체는 건드리지 않고 새로운 객체를 생성해주어야 한다
- 리덕스에서 불변성을 유지해야 하는 이유는 내부적으로 데이터가 변경되는 것을 감지하기 위해 얕은 비교 검사를 하기 때문이다.
- 리듀서는 순수한 함수
- 변화를 일으키는 리듀서 함수는 순수한 함수여야 한다.
- 리듀서 함수는 이전 상태와 액션 객체를 파라미터로 받는다
- 파라미터 외의 값에는 의존하면 안 된다.
- 이전 상태는 절대로 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환한다.
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야 한다.
- 변화를 일으키는 리듀서 함수는 순수한 함수여야 한다.
https://samuel-santosgdmg.medium.com/the-problem-of-a-react-application-without-redux-4735cf60ac9