똑같은 삽질은 2번 하지 말자
React vol.10 (Redux 관리, Redux-Thunk) 본문
개요
React JS 를 공부하면서 기본을 정리해두고자 작성
Redux를 쓸 때 고려 해야하는 부분이 있다.
1. Redux의 상태에 관한 동기 처리
2.Redux의 상태에 관한 비동기 처리
1 은 컴포넌트 안에서 처리할 수도 있지만, 그렇게되면 Redux의 상태를 사용하는 모든 컴포넌트에 해당 로직을 배치해야하기 때문에
보통은 Reducer에 두고 처리하는게 효율적이라고 말할 수 있다.
2 이 문제인데 Redux에서는 비동기 처리에 대해서는 절대 Reducer에 두면 안된다. 이 이유는 Vuex를 배울 때도 느꼈지만 Redux의 Reducer는 state에 접근해 상태를 변화시키는 동작을 행하는데 여기에 만약 비동기 코드가 들어가버리면 정의한 로직들이 순차적으로 실행됨을 보장할 수 없게되고 그럼 제대로 state의 상태를 추적할 수 없기 때문이다. 그러므로 Reducer에는 비동기 처리를 넣으면 안된다.
여기서는 선택지가 두개 있는데 각각의 컴포넌트에 비동기 로직을 두어도 되고, Action Creators를 이용해 비동기 로직을 한 곳에 모아 놓을 수 도 있다.
해본적이 없고 주로 쓰이는 방법인 Action Creator를 이용해 이 문제를 해결해보자.
Redux-Thunk란?
우선 Thunk의 의미가 특정 작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼 것을 의미한다.
그럼 Redux-Thunk란 제일 많이 쓰이는 리덕스 미들웨어(특정 작업 사이에 어떤 작업을 두는 개념) 라이브러리다.
Redux-Thunk를 따로 다운로드 할 필요는 없다. 내 환경은 Redux-toolkit으로 Redux를 만들고 있기 때문에 그냥 Action Creator 함수를 만들어 주면 된다.
export const sendCartItem = (cartItem) => {
return async (dispatch) => { // dispatch는 redux-toolkit에서 자동으로 action creator를 구성하면서 넣어준다.
const addCartItem = async () => {
await fetch("http://localhost:7070/api/carts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: cartItem.title,
description: cartItem.description,
price: cartItem.price,
amount: 1,
}),
});
};
dispatch(
uiActions.showNotification({
status: "pending",
title: "Sending",
message: "Sending cart item",
})
);
try {
await addCartItem();
dispatch(
uiActions.showNotification({
status: "success",
title: "Success!",
message: "Success!!!!!",
})
);
// dispatch(cartSlice.cartActions.addItem(cartItem)); 아직 actions가 생성전이라 이렇게 사용할 수 없다.
dispatch(cartActions.addItem(cartItem));
} catch (err) {
console.error(err);
dispatch(
uiActions.showNotification({
status: "error",
title: "Error!",
message: "Error!!!!!",
})
);
}
};
};
const addCartHandler = () => {
dispatch(
sendCartItem({
id,
title,
price,
description,
})
);
};
Action Creator의 역할은 어찌보면 기존에 reducer를 쓰기 위해 dispatch(action)을 하는 과정에서 중간처리로써 달리 말하면 middleware로써의 역할을 하는것이다.
dipatch() 날림 -> reducer로 보내기 전에 비동기처리(Action Creator) -> reducer의 action실행
참고
fetch에는 default로 헤더가 셋팅이 안되서 셋팅을 안해주면 422에러가 발생했다.
(axios는 default로 header에 application/json으로 되어 있는걸로 알고 있따.)
headers: {
"Content-Type": "application/json",
},
다음에는 Redux-toolkit 안쓰고 한번 해보자.