Action -> (Call the reducer) -> Reducer ->(Update Store) -> Redux Store -> (Render new view) -> React Component ->(Dispatch Synchronous Action) ->다시 Action으로 회귀...
*Action: 간단한 자바스크립트 객체이다. 여기에는 우리가 수행하는 작업의 유형을 지정하는 type 속성 있다. 선택적으로 redux 저장소에 일부 데이터를 보내는데 사용되는 payload 속성을 가질 수 도 있다.
*Reducer: 애플리케이션 상태의 변경 사항을 결정하고 업데이트된 상태를 반환하는 함수이다.
전체적인 구조도
*Redux Store: 이들을 하나로 모으는 객체 저장소로, 애플리케이션의 전체 상태 트리를 보유한다. 내부 상태를 변경하는 유일한 방법은 해당 상태에 대한 Action을 전달하는 것 뿐이다. 리덕스 스토어는 클래스가 아니라, 몇가지 method를 가진 객체일 뿐이다.
+ Bonus) Props와 State의 차이는?
1) Props
Props는 properties의 줄임말로, 구성요소가 서로 통신하는 방법이다.
상위 구성 요소에서 아래쪽으로 props를 전달하는 흐름을 가진다.
해당 값을 변경하려면 자식 관점에서 props를 변경할 수가 있다. 부모는 내부 상태를 변경해야 한다.
Props 사용 예시
2) State
부모 컴포넌트에서 자식 컴포넌트로 전달 X.
해당 컴포넌트 안에서 data를 전달할 때 State를 사용한다.
State가 변하면 re-render 된다.
ex) 검색창에 글을 입력할 때 글이 변하는 것은 state를 바꾸는 것이다.
State 사용 예시
리덕스 미들웨어란?
Redux middleware dispatch 전달 후 reducer에 도달하는 순간 사이에 사전에 지정된 작업을 실행할 수 있게 해주는 중간자이다. 로깅, 충돌 보고, 비동기 API와 통신, 라우팅 등을 위해 Redux 미들웨어를 사용한다.
아래와 같이 로깅 미들웨어 함수를 생성한다.
실습Part App.tsx 파일을 보면, 로깅 미들웨어 함수에 대한 코드를 볼 수 있다.
리덕스 Thunk란?
리덕스를 사용하는 앱에서 비동기 작업을 할 때 redux-thunk를 많이 사용한다.
비동기 요청은 보통 서버에 요청 보내서 데이터를 가져올때 보낸다.
이것 또한 logger 미들웨어처럼 리덕스 미들웨어이며, 리덕스를 개발한 사람이 만들었다.
*Thunk: 일부 지연된 작업을 수행하는 코드 조각을 의미하는 프로그래밍 용어이다. 지금 일부 논리를 실행하는 대신 나중에 작업을 수행하는 데 사용할 수 있는 함수 본문이나 코드를 작성할 수 있다.
<실습 Part>
코드 작성 후 블로그 정리를 시작하여 순서가 뒤죽박죽일 수 있습니다.
*개발환경 셋팅
작업폴더 생성하여 리액트 앱 설치 + typescript도 이용할 것이므로 해당 모듈도 함께 설치 + redux 설치
npx create-react-app my-app --template typescript
npm install redux --save
//Axios 모듈 나중에 리덕스 Thunk할때 사용해야하므로 redux-thunk와 함께 미리 설치해두자.
npm install axios --save
npm install redux-thunk --save
1) App의 전체 상태 트리를 보유하는 Redux 저장소 생성. 앱 하나에는 무조건 하나의 스토어만 있어야한다.
ADD_TODO action 수행 시, 기존 내용에 새롭게 추가된 action.text를 추가해서 할 일 목록을 생성한다.
-posts.tsx
enumActionType {
FETCH_POSTS="FETCH_POSTS",
DELETE_POSTS="DELETE_POSTS"
}
interfacePost {
userId:number;
id:number;
title:string;
}
interfaceAction {
type:ActionType;
payload:Post[];
}
constposts= (state=[], action:Action)=>{
switch(action.type){
case'FETCH_POSTS':
return [...state, ...action.payload]
default:
returnstate
}
}
exportdefaultposts;
외부 API에서 게시물에 대한 내용을 가져와 웹페이지상에 띄우는 역할을 한다.
-App.tsx 파일
todos, counter, posts action을 수행하는 함수에 대한 UI를 생성하였다.(App.tsx)
=> props 타입과 post 인터페이스를정의했다.
props는 컴포넌트에 전달되는 속성을, post는 게시물 데이터의 구조를 정의한다.
=> App 컴포넌트에서 리덕스의 useDispatch와 useSelector를 사용해서 리덕스와의 상호작용을 설정한다.
useEffect를 사용해 컴포넌트가 마운트 될 때 게시물을 가져오는 작업을 수행한다.
=> fetchPosts 함수는 비동기 thunk 함수를 반환한다. 이 함수는 axios를 사용해 외부 API에서 게시물 데이터를 가져온다.
가져온 데이터는 'FETCH_POSTS' action type과 함께 dispatch된다.
=> 이벤트 핸들러는 handleChange와 addTodo가 있는데, handleChange는 todo 입력필드의 변경을 처리하고, addTodo는 새 todo를 추가하는 폼 제출을 처리한다.
=> UI 부분에서는 Redux 스토어의 counter, todos, posts 상태를 사용해 화면에 정보를 표시한다. 각 todo와 게시물은 리스트로 표시된다.
=> counter, todos, posts 상태는 Redux 스토어에서 가져온다. 버튼을 클릭하면 onIncrement, onDecrement 함수가 각각 호출돼서 counter 값을 변경한다.(증감연산 수행). todo에 대해서는 form 제출 시 ADD_TODO 액션과 함께 Redux 스토어로 Dispatch되어서 todo리스트에 해당 항목이 추가되게 된다.
이와 같이 Redux를 사용해 애플리케이션의 상태를 관리하고, axios로 외부 API에서 데이터를 가져와 화면에 표시하는 간단한 상태관리앱을 실습해보았다.