如何在 nextjs 中正确实现 toast-ui/calendar

How to properly implement toast-ui/calendar in nextjs

我正在尝试实现@toast-ui/react-calendar,最初我得到的是 window is not defined 但在实现修复后我得到了这里 https://github.com/nhn/toast-ui.react-calendar/issues/39,我得到了这个 未处理的运行时错误错误:元素类型无效:应为字符串(对于内置组件)或 class/function(对于复合组件)但得到:对象。您可能忘记从定义它的文件中导出您的组件,或者您可能混淆了默认导入和命名导入。检查 __WEBPACK_DEFAULT_EXPORT__.

的渲染方法

这是我当前的代码

CalendarPage.js

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

import 'tui-calendar/dist/tui-calendar.css';
import 'tui-date-picker/dist/tui-date-picker.css';
import 'tui-time-picker/dist/tui-time-picker.css';

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

日程>index.jsx

import { forwardRef, useCallback, useRef, useState } from 'react';
import dynamic from 'next/dynamic';

const TuiCalendar = dynamic(() => import('@components/calendars/CalendarPage'), { ssr: false });
const CalendarWithForwardedRef = forwardRef((props, ref) => (
    <TuiCalendar {...props} forwardedRef={ref} />
));

const start = new Date();
const end = new Date(new Date().setMinutes(start.getMinutes() + 30));
const schedules = [
    {
        calendarId: '1',
        category: 'time',
        isVisible: true,
        title: 'Study',
        id: '1',
        body: 'Test',
        start,
        end,
    },
    {
        calendarId: '2',
        category: 'time',
        isVisible: true,
        title: 'Meeting',
        id: '2',
        body: 'Description',
        start: new Date(new Date().setHours(start.getHours() + 1)),
        end: new Date(new Date().setHours(start.getHours() + 2)),
    },
];

const calendars = [
    {
        id: '1',
        name: 'My Calendar',
        color: '#ffffff',
        bgColor: '#9e5fff',
        dragBgColor: '#9e5fff',
        borderColor: '#9e5fff',
    },
    {
        id: '2',
        name: 'Company',
        color: '#ffffff',
        bgColor: '#00a9ff',
        dragBgColor: '#00a9ff',
        borderColor: '#00a9ff',
    },
];

const SchedulePage = () => {
    const cal = useRef(null);

    const onClickSchedule = useCallback((e) => {
        const { calendarId, id } = e.schedule;
        const el = cal.current.calendarInst.getElement(id, calendarId);

        console.log(e, el.getBoundingClientRect());
    }, []);

    const onBeforeCreateSchedule = useCallback((scheduleData) => {
        console.log(scheduleData);

        const schedule = {
            id: String(Math.random()),
            title: scheduleData.title,
            isAllDay: scheduleData.isAllDay,
            start: scheduleData.start,
            end: scheduleData.end,
            category: scheduleData.isAllDay ? 'allday' : 'time',
            dueDateClass: '',
            location: scheduleData.location,
            raw: {
                class: scheduleData.raw['class'],
            },
            state: scheduleData.state,
        };

        cal.current.calendarInst.createSchedules([schedule]);
    }, []);

    const onBeforeDeleteSchedule = useCallback((res) => {
        console.log(res);

        const { id, calendarId } = res.schedule;

        cal.current.calendarInst.deleteSchedule(id, calendarId);
    }, []);

    const onBeforeUpdateSchedule = useCallback((e) => {
        console.log(e);

        const { schedule, changes } = e;

        cal.current.calendarInst.updateSchedule(schedule.id, schedule.calendarId, changes);
    }, []);

    function _getFormattedTime(time) {
        const date = new Date(time);
        const h = date.getHours();
        const m = date.getMinutes();

        return `${h}:${m}`;
    }

    function _getTimeTemplate(schedule, isAllDay) {
        var html = [];

        if (!isAllDay) {
            html.push('<strong>' + _getFormattedTime(schedule.start) + '</strong> ');
        }
        if (schedule.isPrivate) {
            html.push('<span class="calendar-font-icon ic-lock-b"></span>');
            html.push(' Private');
        } else {
            if (schedule.isReadOnly) {
                html.push('<span class="calendar-font-icon ic-readonly-b"></span>');
            } else if (schedule.recurrenceRule) {
                html.push('<span class="calendar-font-icon ic-repeat-b"></span>');
            } else if (schedule.attendees.length) {
                html.push('<span class="calendar-font-icon ic-user-b"></span>');
            } else if (schedule.location) {
                html.push('<span class="calendar-font-icon ic-location-b"></span>');
            }
            html.push(' ' + schedule.title);
        }

        return html.join('');
    }

    const templates = {
        time: function (schedule) {
            console.log(schedule);
            return _getTimeTemplate(schedule, false);
        },
    };

    return (
        <div className='App'>
            <h1>Welcome to TOAST Ui Calendar</h1>
            <CalendarWithForwardedRef
                ref={cal}
                height='1000px'
                useCreationPopup={true}
                useDetailPopup={true}
                calendars={calendars}
                schedules={schedules}
                onClickSchedule={onClickSchedule}
                onBeforeCreateSchedule={onBeforeCreateSchedule}
                onBeforeDeleteSchedule={onBeforeDeleteSchedule}
                onBeforeUpdateSchedule={onBeforeUpdateSchedule}></CalendarWithForwardedRef>
        </div>
    );
};
export default SchedulePage;

我不知道我做错了什么,但我一直收到这个错误

Unhandled Runtime Error
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `__WEBPACK_DEFAULT_EXPORT__`.

Call Stack
createFiberFromTypeAndProps
node_modules\react-dom\cjs\react-dom.development.js (25058:0)
createFiberFromElement
node_modules\react-dom\cjs\react-dom.development.js (25086:0)
reconcileSingleElement
node_modules\react-dom\cjs\react-dom.development.js (14052:0)
reconcileChildFibers
node_modules\react-dom\cjs\react-dom.development.js (14112:0)

原来我的代码问题是由冲突的 npm 包引起的,我之前安装了 react-big-calendar 删除修复了问题