ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swiper - Cannot read properties of undefined (reading 'autoplay')
    Language/React 2024. 11. 7. 11:47

    React에서 Swiper를 추가하고 autoplay를 시키고 해당 화면에서 나오게 되면 아래와 같은 에러가 발생한다.

    Unhandled Runtime Error

    TypeError: Cannot read properties of undefined (reading 'autoplay')

     

     

    원인

    GPT 형님께서 말씀하시길 `TypeError: Cannot read properties of undefined (reading 'stop') 오류가 발생하는 경우는 대개 stop 메서드를 호출하려는 객체가 정의되지 않았거나 아직 초기화되지 않았기 때문입니다. 이 오류는 swiperInstance.autoplay.stop() 호출에서 자주 발생할 수 있는데, autoplay 객체가 아직 인스턴스에 초기화되지 않았거나, 다른 이유로 인해 undefined인 상태일 때 그렇습니다.` 라고 하셨고 테스트 진행해보니 그문제가 맞았다.

     

    방법1

    컴포넌트가 사라질때 stop 및 destroy하는 코드를 추가하였다.

      useEffect(() => {
        // 컴포넌트 언마운트 시 Swiper 인스턴스 정리
        return () => {
          if (swiperInstance) {
            if (swiperInstance.autoplay && swiperInstance.autoplay.stop) {
              swiperInstance.autoplay.stop();
            }
            swiperInstance.destroy(true, true);
          }
        };
      }, [swiperInstance]); // swiperInstance가 변경될 때마다 이 effect를 다시 실행

     

    import React, { useEffect, useState } from 'react';
    
    ...
    
    SwiperCore.use([Autoplay]);
    
    const RollingNotice = () => {
      const [swiperInstance, setSwiperInstance] = useState<SwiperCore | null>(null);
    
      useEffect(() => {
        // 컴포넌트 언마운트 시 Swiper 인스턴스 정리
        return () => {
          if (swiperInstance) {
            if (swiperInstance.autoplay && swiperInstance.autoplay.stop) {
              swiperInstance.autoplay.stop();
            }
            swiperInstance.destroy(true, true);
          }
        };
      }, [swiperInstance]); // swiperInstance가 변경될 때마다 이 effect를 다시 실행
    
      ...
    
      return (
        <div className={cx('wrap-rolling-notices')}>
          <Swiper
            onSwiper={setSwiperInstance} // Swiper 인스턴스를 상태에 저장
            modules={[Autoplay]}
            ...
          >
            {items.map((item, index) => (
              <SwiperSlide ...>
                ...
              </SwiperSlide>
            ))}
          </Swiper>
        </div>
      );
    };
    
    export default RollingNotice;

     

    방법2

    Swiper에서 onBeforeDestroy을 활용하는것이다.

      <Swiper
        onBeforeDestroy={(swiper) => {
          // Ensure autoplay is stopped before component unmounts
          if (swiper.autoplay) {
            swiper.autoplay.stop();
          }
        }}
        ...
      >

     

    <Swiper
      onBeforeDestroy={(swiper) => {
        // Ensure autoplay is stopped before component unmounts
        if (swiper.autoplay) {
          swiper.autoplay.stop();
        }
      }}
      
      ...
    >
      {items &&
        items.map((item, idx) => (
          <SwiperSlide ...>
            ...
          </SwiperSlide>
        ))}
    </Swiper>

     

     

    입맛에 맞게 쓰면 되겠지만 `방법1`은 리액트에서 컴포턴트가 사라질때 컨트롤 하는것이고,  `방법2`는 Swiper 컴포넌트에서 제공되는 함수를 활용 하는것이다.

     

    필자는 `방법2`가 소스 가독성으로도 좋아서 2번 방법으로 적용하였다.

     

     

    추가적인 오류

    swiper.params.autoplay.reverseDirection 이부분에서 에러 발생

    reverseDirection: false 옵션 추가

    <Swiper
        ...
        autoplay={{
          delay: 3000,
          disableOnInteraction: false,
          reverseDirection: false
        }}
        ...
    >
      ...
    </Swiper>

    'Language > React' 카테고리의 다른 글

    react-hook-form을 사용하여 배열 형태 input 사용  (0) 2024.12.02
    타입스크립트 예외처리  (0) 2024.11.22
    Promise 동시에 여러번 호출  (0) 2024.10.15
    push Toast 메시지 만들기  (0) 2024.07.09
    Toast 만들기  (0) 2024.07.09

    댓글

Designed by Tistory.