본문 바로가기

programming/React

[immer] Array for문 돌리면서 연속적인 setState 안되는 이슈

  • 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);