IT, 개발/Error

외부 script 중복 생성 문제 window reset으로 해결하기

  • -
반응형

문제

현재 리액트 앱(Next.js)에서 useEffect를 이용해서 외부에서 스크립트를 불러와서 쓰고 있다. 그런데 return () => { const s = document.getElementById("inlineContent-flixMedia"); s.parentElement.removeChild(s);} cleanup 함수로 변환했음에도 불구하고 컴포넌트를 리렌더링 하였을 때, 스크립트가 두번 생성되는 에러가 발생하였다

스크립트 중복 생성
스크립트 중복 생성

외부 스크립트(flixmedia) : 해당 스크립트는 물건 상세설명 이미지를 만들어주는 스크립트이다
https://www.flixmedia.com/flix-solutions/retailer/faqs

 

FAQs

Flixmedia works with over 1,000 retailers worldwide. This includes most of the world’s largest retailers; Walmart, Tesco, Carrefour, Best Buy, Harvey Norman, JLP, DixonsCarphone, Darty, MediaMarkt, Saturn, Yandex and many more. Almost all of them impleme

www.flixmedia.com

flixmedia

useEffect(() => {
  const s = document.createElement("script");
  s.id = "inlineContent-flixMedia";
  s.type = "text/javascript";
  s.src = AppConfig.NEXT_PUBLIC_INLINE_CDN_FLIXMEDIA_SCRIPT;
  s.async = true;
  s.setAttribute("data-flix-distributor", { distributor_id });
  s.setAttribute("data-flix-language", "{language_code}");
  s.setAttribute("data-flix-brand", "{brand_name}");
  s.setAttribute("data-flix-mpn", "{mpn}");
  s.setAttribute("data-flix-ean", "{ean}");
  s.setAttribute("data-flix-sku", "");
  s.setAttribute("data-flix-button", "flix-minisite");
  s.setAttribute("data-flix-inpage", "flix-inpage");
  s.setAttribute("data-flix-button-image", "");
  s.setAttribute("data-flix-fallback-language", "");
  s.setAttribute("data-flix-price", "");
  document.head.insertBefore(
    s,
    document.head.getElementsByTagName("script")[0]
  );

  return () => {
    const s = document.getElementById("inlineContent-flixMedia");
    s.parentElement.removeChild(s);
  };
}, []);
return <div id="flix-inpage" />;

해결

결론은 windowreset() 전역 함수를 이용한다. flixJsCallbacks 는 window 이벤트를 명명하기 위해서 붙였을 뿐, 별 의미는 없다. (typeof window !== undefined) 는 정의되지 않은 window의 타입이기 때문에 undefied가 발생해도 에러가 발생하지 않게 해준다

    useEffect(() => {
        // 아래의 window 이벤트를 추가해준다.
        if (
            typeof (window as any).flixJsCallbacks === 'object' &&
            typeof (window as any).flixJsCallbacks.reset != 'undefined'
        ) {
            (window as any).flixJsCallbacks?.reset();
        }

        const s = document.createElement('script');
        s.id = 'inlineContent-flixMedia';
        s.type = 'text/javascript';
        ...
        }

        return () => {
            const flixScript = document.getElementById('inlineContent-flixMedia');
            flixScript.parentElement.removeChild(s);
        };
    }, []);
    return <div id="flix-inpage" />;
    ```

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.