[리액트 프로그래밍 정석] 에어비앤비 개발 방식으로 비동기 제어하기
redux-pack이란?
redux-pack은 에어비앤비에서 공개한 비동기 제어를 위한 미들웨어다. redux-pack을 도입하면 비동기 제어에 포함된 복잡한 작업들을 하나의 액션으로 처리할수 있다. (redux-thunk미들웨어보다 더 간단히 비동기 제어 가능!)
Promise 클래스의 비동기 처리 과정을 활용하여 구현되어 있다. redux-pack의 구성을 이해하기 위해 Promise 클래스의 대략적인 구조를 살펴보자면 아래와 같다.

class Promise{
constructor(){
//1. start
}
then(...){
//2. success
}
catch(...){
//3. failure
}
finally(...){
//4. finish
}
}
redux-thunk와 redux-pack의 리듀서 구조 비교하기
redux-thunk의 리듀서는 액션에 대응하는 switch문을 사용해 액션에 맞는 작업을 추가했다. 총 4가지 상황(또는 액션)에 대비하여 코드를 작성해야 한다.
export function thunkReducer(state,action){
const {type,payload}=action;
switch(type){
case 'START':{
return {...state,loading:true};
}
case 'SUCCESS':{
return {...state, payload};
}
case 'FAILURE':{
return {...state,error:true};
}
case 'FINISH':{
return {...state,loading:false};
}
default:
state;
}
}
redux-pack에도 4가지 상황에 대응하는 코드를 작성한다. handle() 함수의 세 번째 인자로 넘어간 객체를 주목하자! start,success,failur,finish의 키값이 리듀서 코드다. handle()함수는 이전 스토어 상태(prevState) 을 이용하여 스토어 데이터에 반영할 객체를 반환한다.
import {handle} from 'redux-pack';
export function packReducer(state,action){
const {type,payload}=action;
if (action==='REDUX_PACK'){
return handle(state,action,{
start:prevState=>({
...prevState,loading:true,
}),
success:prevState=>({...state, payload}),
failure:prevState=>({
...state, error:true,
}),
finish:prevState=>({
...state,
loading:false,
}),
});
}
return state;
}
대용량 데이터 효율적으로 처리하기=> 페이지 개념 도입!
페이지는 전체 데이터를 일정 크기로 쪼갠것을 말한다. useState,useEffect와 자바스크립트 array메소드인 slice를 활용해서 간단히 구현할수 있다.
🐣 https://chanhuiseok.github.io/posts/react-12/ (이거 참고해서 페이지네이션 구현해봐도 괜찮아보임!)
셀렉터로 스토어 데이터 변환하기
지금까지 스토어 데이터를 컴포넌트에 전달하기 위해 mapStateToProps()함수와 데이터 컴포넌트를 조합했다. 그런데 이 방식은 스토어 데이터의 값을 변환하거나 추출하는 등의 작업이 필요해지면 mapStateToProps()함수에 작성한 작업 코드를 전체적으로 수정해야한다는 단점이 있다. 셀렉터는 변경된 스토어 데이터를 화면에 필요한 형태로 변환 및 추출하는 함수를 말한다. 셀렉터를 도입하면 mapStateToProps()함수의 스토어 데이터 변환및 추출 작업을 간단히 대체할수 있다.
스토어와 컴포넌트 사이에 셀렉터가 위치하며, 셀렉터는 스토어 데이터의 값을 받아 변환,추출 등의 작업을 한 다음 반환한 값을 컴포넌트로 넘겨준다. 이전에는 데이터 컴포넌트의 mapStateToProps()함수에서 이 작업들을 모두 담당했지만 이제는 셀렉터가 대신하게 된다.