redux-thunk
- Thunk는 특정 작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼 것을 의미합니다.
- 예를 들어 주어진 파라미터에 1을 더하는 함수를 만들고 싶다면 다음과 같이 작성할 것입니다.
const addOne = x => x + 1;
addOne(1); // 2
- 이 코드를 실행하면 addOne을 호출했을 때 바로 1 + 1이 연산됩니다.
- 그런데 이 연산 작업을 나중에 하도록 미루고 싶다면 어떻게 해야 할까요?
const addOne = x => x + 1;
function addOneThunk (x){
const thunk = () => addOne(x);
return thunk;
}
const fn = addOneThunk(1);
setTimeout(() => {
const value = fn(); // fn이 실행되는 시점에 연산
console.log(value);
}, 1000);
- 만약 addOneThunk를 화살표 함수로만 사용한다면 다음과 같이 구현할 수 있습니다.
const addOne = x => x + 1;
const addOneThunk = x => () => addOne(x);
const fn = addOneThunk(1);
setTimeout(() => {
const value = fn(); // fn이 실행되는 시점에 연산
console.log(value);
}, 1000);
- redux-thunk는 액션 생성 함수에서 일반 액션 객체를 반환하는 대신에 함수를 반환합니다.
- increaseAsync와 decreaseAsync 함수를 만들어 카운터 값을 비동기적으로 한번 변경시켜 봅시다.
// 1초 뒤에 increase 혹은 decrease 함수를 디스패치함
export const increaseAsync = () => dispatch => {
setTimeout(() => {
dispatch(increase());
}, 1000);
};
export const decreaseAsync = () => dispatch => {
setTimeout(() => {
dispatch(decrease());
}, 1000);
};
- API를 요청해야 할 때마다 17줄 정도 되는 thunk 함수를 작성하는 것과 로딩 상태를 리듀서에서 관리하는 작업은 귀찮을 뿐 아니라 코드도 길어지게 만듭니다.
- 그러므로 반복되는 로직을 따로 분리하여 코드의 양을 줄여 봅시다.
export default function createRequestThunk(type, request) {
// 성공 및 실패 액션 타입을 정의합니다.
const SUCCESS = </span><span class="co49">${</span><span class="cd2 co34">type</span><span class="co33">}</span><span class="cd2 co31">_SUCCESS;
const FAILURE = </span><span class="co49">${</span><span class="cd2 co34">type</span><span class="co33">}</span><span class="cd2 co31">_FAILURE;
return params => async dispatch => {
dispatch({ type }); // 시작됨
try {
const response = await request(params);
dispatch({
type: SUCCESS,
payload: response.data
}); // 성공
} catch (e) {
dispatch({
type: FAILURE,
payload: e,
error: true
}); // 에러 발생
throw e;
}
};
}
// 사용법: createRequestThunk(‘GET_USERS‘,api.getUsers);
- 컨테이너 컴포넌트에서 try/catch 구문을 사용하여 에러 값을 조회할 수도 있습니다.
useEffect(() => {
// useEffect에 파라미터로 넣는 함수는 async로 할 수 없기 때문에
// 그 내부에서 async 함수를 선언하고 호출해 줍니다.
const fn = async () => {
try {
await getPost(1);
await getUsers(1);
} catch (e) {
console.log(e); // 에러 조회
}
};
fn();
}, [getPost, getUsers]);
'react를 다루는 기술' 카테고리의 다른 글
18. 리덕스 미들웨어를 통한 비동기 작업 관리(1) (0) | 2022.06.23 |
---|---|
17. 리덕스를 사용하여 리액트 애플리케이션 상태 관리하기(3) (0) | 2022.06.22 |
17. 리덕스를 사용하여 리액트 애플리케이션 상태 관리하기(2) (0) | 2022.06.21 |
17. 리덕스를 사용하여 리액트 애플리케이션 상태 관리하기(1) (0) | 2022.06.20 |
16. 리덕스 라이브러리 이해하기 (0) | 2022.06.18 |