2022-01-31

Lazy initial state

Carousel item의 너비를 반응형으로 구현하기 위해 함수를 사용하게 되어 useState 내부에서 함수를 호출해 initial state값을 지정해주었다.

하지만 리렌더링할때마다 해당 함수가 불필요하게 호출되는 문제가 발생했다.

 const [itemWidth, setItemWidth] = useState(
    calcWidth(windowWidth, CAROUSEL.PADDING, CAROUSEL.ITEM_MAX_WIDTH),
  );

해결방법:

공식문서에 언급된 Lazy initial state를 사용하여 해결.

The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded.

  const [itemWidth, setItemWidth] = useState(() =>
    calcWidth(windowWidth, CAROUSEL.PADDING, CAROUSEL.ITEM_MAX_WIDTH),
  );
  const [paddedItems, setPaddedItems] = useState(() =>
    paddingToItem(items, CAROUSEL.PADDING_DATA),
  );

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ PREV: number; NEXT: number; }'. No index signature with a parameter of type 'string' was found on type '{ PREV: number; NEXT: number; }'.

infinite carousel을 구현하고 있는 중에 다음과 같은 에러가 발생했다.
원인은 CAROUSEL.HANDLE_TYPE property에 string으로 Key에 접근하려고 하기 때문에 발생하는 에러이다.

const CAROUSEL = {
  PADDING_DATA: 2,
  PADDING: 80,
  TRANSITION_TIME: 500,
  HANDLE_TYPE: {
    PREV: -1,
    NEXT: 1,
  },
  ITEM_MAX_WIDTH: 1250,
};


function handleCarousel(type: string) {
  const nextIdx = curIdx + CAROUSEL.HANDLE_TYPE[type];
 // 생략...
}


<CarouselButton
  isClicked={isClicked}
  onClick={() => handleCarousel('NEXT')}
/>

해결방식:

keyof typeof을 사용해서 property만 뽑아내서 명시적으로 type을 제한하는 방식으로 해결하였다.

export type HANDLETYPE = keyof typeof CAROUSEL.HANDLE_TYPE;

function handleCarousel(type: HANDLETYPE) {
  const nextIdx = curIdx + CAROUSEL.HANDLE_TYPE[type];
  // 생략...
}

Reference

좋은 웹페이지 즐겨찾기