Next - element is not defined (tui-calender)

 

element is not defined 오류 해결

프로젝트에서 tui-calendar를 이용하여 캘린더를 구성하여 개발하고 있는데.. <Link>로 이동하는 페이지는 오류가 나지않는데 URL로 (페이지에서 새로고침) 들어가면 아래와 같은 오류가 났다.



계속 개발 하면서 수정하고 새로고침하면 오류가났다. 그래서 첫 페이지로 가서 <Link>로 이동하는 고생을 하였다.

이유를 찾아보니까 <Link>로 가면 CSR이고 URL로 (페이지에서 새로고침)으로 가면 SSR이였던 것이다.
SSR였기 때문에 window객체를 못찾았던것이였다… 서버에서 웹 페이지를 렌더링할 땐 window, document등의 object가 없기 때문에 발생한다. 여기서 내가 사용한 Tui-calendar가 SSR를 지원하지 않는것 같다 ㅠㅠ

그러다 검색을 통해 next/dynamic 을 알게되었다.
https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr이 링크에 설명이 잘 되어있다.
모듈에 브라우저에서만 작동하는 라이브러리가 포함되어있는 경우 작동하게 해주는 라이브러리이다.

npm i @next-tools/dynamic

next/dynamic을 하니까 설치가 안되길래 구글링하니까 @next-tools/dynamic이 나와서 설치해줬다.

import dynamic from 'next/dynamic';
// ... 다른 코드들 생략
const TuiCalendar = dynamic(() => import('@toast-ui/react-calendar'), {
  ssr: false
});
// ... 다른 코드들 생략
return(
    <>
    // ... 다른 코드들 생략
    <TuiCalendar
      ref={cal}
      height="800px"
      view="month"
      useCreationPopup
      useDetailPopup
      template={templates}
      calendars={categories}
      schedules={calendars}
      onBeforeCreateSchedule={onBeforeCreateSchedule}
      onBeforeDeleteSchedule={onBeforeDeleteSchedule}
      onBeforeUpdateSchedule={onBeforeUpdateSchedule}
    />
    // ... 다른 코드들 생략
    </>
);

이제 element is not defined 못찾는다는 오류는 사라졌지만… 새로운 오류! 등장



dynamic때문에 ref를 제대로 사용할 수 없어서 캘린더 내용을 가져올 수 없었다.
달력만 뜨고.. 등록,수정,삭제가 안되는 …쓸모없는 상태가 되었다
React.fowardRef()를 사용하여 ref를 하부 다른 컴포넌트로 전달하는 방법을 사용하였다.

React.forwardRef는 전달받은 ref 어트리뷰트를 하부 트리 내의 다른 컴포넌트로 전달하는 React 컴포넌트를 생성합니다.

사용법 : https://reactjs.org/docs/forwarding-refs.html

components/Calendar/TuiCalendar

import React from 'react';
import Calendar from '@toast-ui/react-calendar';

export default (props) => <Calendar {...props} ref={props.forwardedRef} />;

pages/calendar

// dynamic 사용
const TuiCalendar = dynamic(() => import('../../components/Calendar/TuiCalendar'), {
  ssr: false
});
const CalendarComponent = React.forwardRef((props, ref) => <TuiCalendar {...props} forwardedRef={ref} />);

const Calendar = () => {
    const cal = useRef(null);
    // ... 다른 코드들 생략
    return(
        <>
        ...
        <CalendarComponent
          ref={cal}
          height="800px"
          view="month"
          // ...속성생략
        />
        </>
    );
};
// ... 다른 코드들 생략

const cal = useRef(null);를 만들어서 CalendarRef의 ref로 전달해준다.
React.forwardRef를 통해 하위 컴포넌트로 forwardedRef이용하여 보낸다.
components/Calendar/TuiCalendar 에서 ref로 tuicalendar 컴포넌트로 보낸다.

:laughing: 드디어 성공!! 새로고침해도 오류가 나지 않는다.