Инициализация сторонней библиотеки с использованием React-хуков - PullRequest
0 голосов
/ 06 апреля 2020

Я хочу инициализировать экземпляр Swiper , когда определенный компонент монтируется с использованием перехватчиков React. При изменении размера я хочу уничтожить или обновить экземпляр Swiper в зависимости от ширины области просмотра.

Я инициализирую плагин с ловушкой useEffect, где я вызываю функцию, сохраненную как const.

const MyComponent = () => {
  const [swiper, setSwiper] = useSate(null);
  const element = useRef(null);

  const initSwiper = useCallback(() => {
    // swiper is always null here so I can't destroy the instance
    if (MediaQuery.is('large up') && swiper !== null) {
      return setSwiper(swiper.destroy());
    }

    if (MediaQuery.is('small up')) {
      const currentSwiper = new Swiper(element.current, swiperSettings);
      currentSwiper.init();

      return setSwiper(currentSwiper);
    }
  }, [swiper, swiperSettings]);

  useEffect(() => {
    initSwiper();
    window.addEventListener('resize', initSwiper);

    return () => {
      window.removeEventListener('resize', initSwiper);
    }
  }, []);

  return (
    <div ref={element}>...</div>
}

Я хотел бы знать, как я могу получить доступ к экземпляру Swiper после инициализации. Должен ли я использовать ref? Я не совсем уверен, что лучший способ справиться с этим.

1 Ответ

1 голос
/ 06 апреля 2020

Тебе на самом деле здесь не нужно государство. Поскольку обратный вызов useEffect() является замыканием, и вы не используете swiper вне замыкания, создайте переменную (let swiper) и назначьте переменную текущий экземпляр Swiper. Вы также должны объявить initSwiper внутри замыкания, и вам не нужно (и на самом деле нельзя) обернуть его useEffect(), поскольку блок useEffect() работает только при инициализации.

Примечание : swiperSettings не происходят из реквизита или состояния, поэтому блок useEffect() не зависит от них. Если вам нужно изменить его с помощью props, передайте их по ссылке

const MyComponent = () => {
  const element = useRef(null);

  useEffect(() => {
    let swiper = null;

    const initSwiper = () => {
      if (MediaQuery.is('large up') && swiper !== null) {
        swiper = swiper.destroy();
      } else if (MediaQuery.is('small up')) {
        // swiper.destroy(); // should probably start by destroying the old swiper
        swiper = new Swiper(element.current, swiperSettings);
        swiper.init();
      }
    };

    window.addEventListener('resize', initSwiper);

    return () => {
      window.removeEventListener('resize', initSwiper);
    }
  }, []);

  return (
    <div ref={element}>...</div>
  );
};

И используйте в качестве пользовательского хука (как подсказывает @ PatrickRoberts ):

const useSwiper = () => {
  const element = useRef(null);

  useEffect(() => {
    let swiper = null;

    const initSwiper = () => {
      if (MediaQuery.is('large up') && swiper !== null) {
        swiper = swiper.destroy();
      } else if (MediaQuery.is('small up')) {
        // swiper.destroy(); // should probably start by destroying the old swiper
        swiper = new Swiper(element.current, swiperSettings);
        swiper.init();
      }
    };

    window.addEventListener('resize', initSwiper);

    return () => {
      window.removeEventListener('resize', initSwiper);
    }
  }, []);

  return element;
};

const MyComponent = () => (
  <div ref={useSwiper()} />
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...