티스토리 뷰
React - (Redux state)props변화에따른 saga와 componentWillReceiveProps()에 대한 생각 및 활용
Ideveloper2 2018. 5. 28. 14:22React
: props변화에따른 saga와 componentWillReceiveProps()에 대한 생각 및 활용
| 시작하기에 앞서,
일단 componentWillReceiveProps는 리액트 주기중, props에 변화가 있을때, 그 props를 catch하여 이전 props와 변화한 props를 비교등을 통해, 리액트 웹앱의 세부작업을 할수있는 주기이다.
사내 사이트를 만들던 중, 카트에 자동으로 메뉴가 하나 추가하는 기능을 구현했어야 했는데,
그 케이스가 아래의 두가지였다.
1. 처음사이트에 들어왔을때 유저 ux를 위해 카트에 메뉴를 하나추가
2.예약기능을 위해 날짜를 변경했을시 다시 카트를 clear하고 메뉴를 하나 추가
| 어려움을 겪었던 부분
기존에 1. 처음사이트에 들어왔을때 유저 ux를 위해 카트에 메뉴를 하나추가 기능은 이미 구현이 되어있었고, 예약기능이 추가되었기에 2.예약기능을 위해 날짜를 변경했을시 다시 카트를 clear하고 메뉴를 하나 추가의 case가 추가되었었는데, 아래가 기존의 1. 처음사이트에 들어왔을때 유저 ux를 위해 카트에 메뉴를 하나추가를 위한 redux saga 함수부분이다.
> 1. 처음사이트에 들어왔을때 유저 ux를 위해 카트에 메뉴를 하나추가해줬던 부분
export function* getOrderAmount(actions) {
const { params } = actions;
const { dailies, cart } = yield select();
const orderAmount = yield call(getAmount, params);
yield put(getOrderAmountSuccess(orderAmount));
맨마지막에 cart가 비었으면 1추가
if (Object.keys(cart).length === 0) {
yield put(clearCart());
yield put(addCart({ menuId: dailies.dailies.data[0].menuIdx, amount: 1 }));
}
}
getOrderAmount에 cart가 비었으면 addCart 액션생성함에 액션을 dispatch하는 식으로 구현하였는데, 그이유는 cart에 추가되는 액션은 제일 마지막에 불려야 한다고 생각했고, redux dev tool로 확인한 결과 getOrderAmount(날짜,메뉴,회사 주소별 주문수를 트래킹하는 api에 호출하여 그 개수를 return해줌)부분이 제일마지막에 불리고있는 부분이었고 따라서 그 부분에 아래와 같은 cart state에 아무것도 없는것을 확인해 addcart를 해주는 식으로 해주었었다.
if (Object.keys(cart).length === 0) {
yield put(clearCart());
yield put(addCart({ menuId: dailies.dailies.data[0].menuIdx, amount: 1 }));
}
> 2.예약기능을 위해 날짜를 변경했을시 다시 카트를 clear하고 메뉴를 하나 추가하는 부분
2.예약기능을 위해 날짜를 변경했을시 다시 카트를 clear하고 메뉴를 하나 추가하는 부분은 아래와 같이, componentWillReceiveProps 주기안에 this.props.dailies.data[0].menuIdx !== dailies.data[0].menuIdx 과 같이 불러온 메뉴가 다를시 (날짜에 따라 menu가 바뀌므로) cart에 add해주는식으로 구현했었다.
componentWillReceiveProps(nextProps) {
// 예약시간 변경될때, 맨처음 메뉴를불러올때 cart clear 해주고 카트 다시추가
if (
(this.props.dailies.data &&
this.props.dailies.data[0] &&
this.props.dailies.data[0].menuIdx !== dailies.data[0].menuIdx)
) {
this.props.clearCart();
this.props.addCart({
menuId: dailies.data[0].menuIdx,
amount: 1,
});
}
}
export function* getOrderAmount(actions) {
const { params } = actions;
const { dailies, cart } = yield select();
const orderAmount = yield call(getAmount, params);
yield put(getOrderAmountSuccess(orderAmount));
// 맨마지막에 cart가 비었으면 1추가
// if (Object.keys(cart).length === 0) {
// yield put(clearCart());
// yield put(addCart({ menuId: dailies.dailies.data[0].menuIdx, amount: 1 }));
// }
}
아래와 같이, componentWillReceiveProps 주기에서 addCart하는식으로 구현해주었다.결국 addCart 액션생성함수는 api호출로 받은 여러 props에 변화에 따라서 카트에 추가해주는 그 case가 두가지로 나뉘는 것에 따른 가능 구현이므로 componentWillReceiveProps 주기에서 아래와 같이 if에 case들을 묶어 처리해주는 방식으로 처리해주는게 더 옳은것이었다.
if (
(this.props.dailies.data &&
this.props.dailies.data[0] &&
this.props.dailies.data[0].menuIdx !== dailies.data[0].menuIdx) ||
(Object.keys(cart).length === 0 &&
this.props.meta.timeSlot !== meta.timeSlot)
)
위는 case에 따른 if 조건들이고,
1. 처음사이트에 들어왔을때 유저 ux를 위해 카트에 메뉴를 하나추가 Object.keys(cart).length === 0 && this.props.meta.timeSlot !== meta.timeSlot)
2.예약기능을 위해 날짜를 변경했을시 (메뉴가변경됨) 다시 카트를 clear하고 메뉴를 하나 추가 this.props.dailies.data && this.props.dailies.data[0] && this.props.dailies.data[0].menuIdx !== dailies.data[0].menuIdx
아래는 전체 함수부분이다.
componentWillRecieveProps(nextProps){
// 예약시간 변경될때, 맨처음 메뉴를불러올때 cart clear 해주고 카트 다시추가
if (
(this.props.dailies.data &&
this.props.dailies.data[0] &&
this.props.dailies.data[0].menuIdx !== dailies.data[0].menuIdx) ||
(Object.keys(cart).length === 0 &&
this.props.meta.timeSlot !== meta.timeSlot)
) {
this.props.clearCart();
this.props.addCart({
menuId: dailies.data[0].menuIdx,
amount: 1,
});
}
}
| 느낀점
saga 함수에서는 yield 로 동기적인 순서로 기능을 수행하긴 하지만, props에 변화에따른 기능구현은 cover가 어려우므로, saga함수에서는 그런 props변화에따라 기능을 구현해야하는것은 고려할 필요가 없는것같다.
또한 한 saga 함수에서 여러가지 기능을 수행하게 하면 안되며, api call이나, 다른 액션 디스패치에 뒤따르는 다른액션을 디스패치해주는 등의 확장된 역할을 수행해주면 되는것이고, 이전 props와 바뀐 props 변화에 따른 (redux state가 props로 매칭되므로 redux state의 변화도 포함한다.) 특정 기능을 수행할때는componentWillReceiveProps(nextProps) 에서 그 기능을 구현해줘야 하는것이었다.
'Front end > React' 카테고리의 다른 글
React - 리액트에서 mount 와 render의 차이 (0) | 2018.06.09 |
---|---|
React -Redux saga (takeEvery함수와 take) (0) | 2018.06.01 |
React - navbar item 클릭 후 Link to로 링크 이동시, navbar toggle 되게하기 (0) | 2018.05.24 |
React - 네이버 맵 api 활용하기 (0) | 2018.05.12 |
React -redux thunk, redux saga (0) | 2018.03.07 |