강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

신지수님의 프로필 이미지
신지수

작성한 질문수

페이지 이탈 방지

작성

·

7

0

const hasChanges = useMemo(() => {
    if (!twinClip) {
      return events.length > 0;
    }
    const baseline = {
      title: twinClip.title || '',
      description: twinClip.description || '',
      visibility: twinClip.visibility,
      category: twinClip.category || [],
      reference: twinClip.reference || [],
      events: twinClip.script.events || [],
      timeRange: [twinClip.script.timeRange.min, twinClip.script.timeRange.max] as [number, number],
      hasThumbnailFile: false,
    };
    const current = {
      title: watch('title') || '',
      description: watch('description') || '',
      visibility,
      category,
      reference: reference.map((i) => i.content),
      events,
      timeRange: [timeRange?.[0]?.getTime?.() ?? 0, timeRange?.[1]?.getTime?.() ?? 0] as [
        number,
        number,
      ],
      hasThumbnailFile: Boolean(thumbnailFile),
    };
    return !isEqual(baseline, current);
  }, [
    twinClip,
    events,
    timeRange,
    watch('title'),
    watch('description'),
    visibility,
    category,
    reference,
    thumbnailFile,
  ]);

  useEffect(() => {
    const isShowTutorial = localStorage.getItem('authorTutorial');
    if (!isShowTutorial) {
      localStorage.setItem('authorTutorial', 'true');
      setTutorialOpen(true);
    }
  }, []);

  useEffect(() => {
    if (!hasChanges || isSaving) return;

    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      e.preventDefault();
      e.returnValue = '';
    };

    const originalPush = router.push;
    const originalBack = router.back;

    const cleanup = () => {
      removeEventListener('beforeunload', handleBeforeUnload);
      removeEventListener('popstate', handlePopState);
      router.push = originalPush;
      router.back = originalBack;
    };

    const handlePopState = () => {
      if (confirm(LEAVE_WARNING)) {
        cleanup();
        history.back();
        return;
      }

      removeEventListener('popstate', handlePopState);
      history.forward();
      setTimeout(() => {
        addEventListener('popstate', handlePopState);
      }, 10);
    };

    history.pushState(null, '', location.href);

    addEventListener('beforeunload', handleBeforeUnload);
    addEventListener('popstate', handlePopState);

    router.push = ((...args: Parameters<typeof originalPush>) => {
      if (confirm(LEAVE_WARNING)) {
        return originalPush(...args);
      }
      return Promise.resolve(false);
    }) as typeof router.push;

    router.back = (() => {
      if (confirm(LEAVE_WARNING)) {
        cleanup();
        return originalBack();
      }
    }) as typeof router.back;

    return () => {
      cleanup();

      if (ignoreFirstCleanupRef.current) {
        ignoreFirstCleanupRef.current = false;
        return;
      }
      if (hasChanges) {
        trackClipSaveFail();
      }
    };
  }, [hasChanges, isSaving]);

현재 코드에서 새로고침, 나가기 이탈은 잘 됩니다.
생성 페이지

취소 버튼 → 컨펌창 → 확인 → 아무 효과 없음 → 다시 취소 버튼 → 컨펌창 없이 캔설 적용

 

편집 페이지

뒤로가기 → 컨펌창 → 확인 → 아무 효과 없음 → 다시 뒤로가기 여러 번 눌러야 뒤로가기 적용 이땐 컨펌창 없이 뒤로 가기됨

취소 버튼 → 컨펌창 → 확인 → 아무 효과 없음 → 다시 취소 버튼 여러 번 눌러야 뒤로가기 적용

이런 버그가 있는데요, 저는 컨펌창이 뜨고 확인을 눌렀을 때 바로 뒤로가기나 취소가 적용이 되었으면 하는데 왜 이런 문제가 발생하고, 어떻게 해결할 수 있나요 ?

답변

답변을 기다리고 있는 질문이에요
첫번째 답변을 남겨보세요!
신지수님의 프로필 이미지
신지수

작성한 질문수

질문하기