- setState 업데이트는 async 작업이다
- 연속적으로 빠르게 도는 경우 모든 update를 보장할 수 없다
- immer 의 produce 함수 안에서 필요한 내용을 만들어서 setState 한다→ Functional update form of the state setter
Bad Case
// 1. MLList 필터링 & 인덱스 찾기
const targetIdxList = checkedProductId.map((item) => {
return productListData[productPackageIdx].MLList.findIndex((el) => el.productId === item);
});
// 2. 인덱스 맵 돌려서 값 변경
targetIdxList.forEach((itemIdx) => {
if (itemIdx >= 0) {
const nextState = produce(productListData, (draftState) => {
draftState[productPackageIdx].MLList[itemIdx].plpSize = e.target.value;
});
setProductListData(nextState);
}
});
화면
- 타겟 idx 를 찾아서 for 문을 돌리지만, 맨 마지막 인덱스값만 “L” 로 변경이 되고, 이전 값들은 변경이 되지 않는다
- BEFORE
- AFTER
Good Case
- 함수형으로 생성하여 update 한다
// Combine both updates into a single update
const combinedStateUpdate = produce(nextState, (draftState) => {
// 1. MLList 필터링 & 인덱스 찾기
const targetIdxList = checkedProductId.map((item) => {
return draftState[productPackageIdx].MLList.findIndex((el) => el.productId === item);
});
// 2. 인덱스 맵 돌려서 값 변경
targetIdxList.forEach((itemIdx) => {
if (itemIdx >= 0) {
draftState[productPackageIdx].MLList[itemIdx].plpSize = e.target.value;
}
});
});
setProductListData(combinedStateUpdate);