React Redux
Table of contents
Action(액션)
상태에 변화가 필요하면 액션이 발생한다. 액션은 하나의 객체로 표현된다.
{type: 'ADD_TODO'data: {id: 1,content: 'text',completed: false}}
액션 객체(action object)는 반드시 type 필드를 가지고 있어야 한다. 이 값은 액션의 이름이라 할 수 있다. 그 외에 값들은 상태를 업데이트 할 때 참고해야 할 값이다.
Action creator(액션 생성 함수)
이름 그대로 액션 객체를 만들어 주는 함수
// 함수function addTodo( data ) {return {type: 'ADD_TODO',data};}// 화살표 함수const addTodo = data => ({type: 'ADD_TODO',data});
변화를 발생 시켜야 할 때 매번 액션 객체를 직접 작성하는 것이 아니라 함수로 만들어서 관리한다.
Reducer(리듀서)
액션을 만들어 발생시키면 리듀서가 현재 상태와 전달받은 액션 객체를 파라미터로 받아 온 뒤, 두 값을 참고하여 새로운 상태를 만들어 반환한다.
Store(스토어)
한 개의 프로젝트는 하나의 스토어를 가진다 있다. 스토어 안에는 현재 애플리케이션 상태와 리듀서, 그 외에 중요한 내장 함수를 가지고있다.
Dispatch(디스패치)
스토어의 내장 함수 중 하나, 디스패치 함수는 dispatch(action)
과 같은 형태로 액션 객체를 파라미터로 넣어서 호출한다. 디스패치가 호출되면 스토어는 리듀서 함수를 실행시켜 새로운 상태를 만들어 낸다.
Subscribe(구독)
스토어의 내장 함수 중 하나, Subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출하면, 리스너 함수는 액션이 디스패치되어 상태가 업데이트될 때마다 호출된다.
리덕스의 세 가지 규칙
1. 단일 스토어
여러 개의 스토어를 사용하는 것이 불가능 한것은 아니나 관리가 복잡해질 수 있으므로 권장하지 않는다.
2. 읽기 전용 상태
redux state는 읽기 전용, 상태를 업데이트할 때 원본 객체를 변경하지 않고 새로운 객체를 생성해야 한다.(= 불변성 유지) 객체의 변화(데이터 변경)를 감지 할 때 얕은 비교 검사를 하기 때문이다. (복잡한 자료 구조를 가진 데이터라면 변화 감지를 못 할수 있다)
3. 리듀서는 순수한 함수
리듀서는 순수 함수여야 한다.
- 이전 상태와 액션 객체를 파라미터로 받는다.
- 파라미터 외의 값은 의존하거나 참조하면 안 된다.
- 이전 상태를 변경해선 안 된다. (깊은 복사를 해서 사용)
- 새로운 상태 객체를 만들어 반환해야 한다.
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야 한다.
리듀서 함수 내부에서 랜덤 값 생성, Date 함수를 사용해 현재 시간을 가져오거나, 네트워크 요청 등을 한다면 파라미터가 같아도 다른 결과물을 만들어 낸다. 이러한 작업들은 리듀서 함수 바깥에서 처리해야 한다. 액션을 만드는 과정에서 처리하거나, 네트워크 요청같이 비동기 작업은 리덕스 미들웨어에서 처리, 관리한다.
리덕스 디렉터리 구조와 패턴
프레젠테이션 컴포넌트와 컨테이너 컴포넌트
프레젠테이션 컴포넌트 : 상태 관리가 이루어지지 않고, props를 받아와 UI를 보여주기만 하는 컴포넌트
컨테이너 컴포넌트 : 리덕스와 연동되어 상태를 받아오고, 리덕스 스토어에 액션을 디스패치한다. 이 패턴을 사용하면 코드의 재사용성도 높아지고, 관심사의 분리가 이루어져 UI를 작성할 때 편함
일반적인 패턴
각 세 가지의 디렉터리를 만들고 그 안에 기능별로 파일을 하나씩 만드는 방식 리덕스 공식 문서에서도 사용된다.
- actions
- constants
- reducers
장점 코드의 종류에 따라 다른 파일에 작성하여 정리할 수 있어 편리
단점 새로운 액션을 만들 때마다 세 종류의 파일을 모두 수정해야 한다.
Ducks 패턴
하나의 디렉터리에 액션 타입, 액션 생성 함수, 리듀서 함수를 기능별로 파일 하나에 다 작성하는 방식