2

Estou com o seguinte erro:

Unhandled Runtime Error Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. 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 Resumos.

Tentei duas formas diferentes que encontrei pra solucionar isso, mas nenhuma resolveu

Forma 1:


import dynamic from "next/dynamic";

const { CKEditor } = dynamic(
  () => {
    return import('@ckeditor/ckeditor5-react');
  },
  { ssr: false }
);

const {ClassicEditor} = dynamic(
  () => {
    return import('@ckeditor/ckeditor5-build-classic');
  },
  { ssr: false }
);

const Resumos = ({id}) => {
  <CKEditor 
       editor={ ClassicEditor }
       data={textoResumoAluno}
       onChange={handleChangeTextoResumoAluno}
  />
}

Forma 2:

const Resumos = ({id}) => {
    const editorRef = useRef()
    const [ editorLoaded, setEditorLoaded ] = useState( false )
    const { CKEditor, ClassicEditor } = editorRef.current || {}

    useEffect( () => {
        editorRef.current = {
          CKEditor: require( '@ckeditor/ckeditor5-react' ),
          ClassicEditor: require( '@ckeditor/ckeditor5-build-classic' )
        }
        setEditorLoaded( true )
    }, [] );


{editorLoaded ? ( 
      <CKEditor
           editor={ ClassicEditor }
           data={textoResumoAluno}
           onInit={ editor => { /*You can store the "editor" and use when it is needed.
                 console.log('Editor is ready to use!', editor)*/
            }}
           onChange={handleChangeTextoResumoAluno}
       /> 
  ) : (
          <div>Editor loading</div>
  )}
}

1 Resposta 1

1

Também tive alguns problemas com o CKEditor no Next.js, no React era só importar e usar, mas como o Next.js renderiza a página no servidor antes de enviar para o Browser, ocorria alguns erros.

A forma que eu encontrei para resolver foi criar um Componente CustomEditor que contêm a importação do CKEditor e do ClassicEditor e depois importar esse componente usando o dynamic.

No meu caso eu não usei o ClassicEditor, mas uma versão customizada que eu gerei pelo site do CKEditor, usando a ferramenta Online Build.

Assim eu poderia usar outras formas de fazer o upload das imagens e usar outros componentes como o Bloco de Código.

Eu criei uma pasta chamada ckeditor5 dentro do projeto Next.js, extrai os arquivos dentro dela e executei o comando de instalação: npm add file:./ckeditor5

Antes de executar o comando você pode editar o arquivo ckeditor5/package.json para escolher um outro nome, tipo "ckeditor5-inline", caso você precise instalar duas ou mais builds customizadas.

O componente CustomEditor ficou assim:

import Editor from 'ckeditor5-custom-build'
import { CKEditor } from '@ckeditor/ckeditor5-react'

export default function CustomEditor({ data, onReady, onChange, onBlur, onFocus }) {

    const editorConfiguration = {/* Essa Configuração você Encontra no arquivo ckeditor5/srcckeditor.js no Objeto Editor.defaultConfig */}

    return (
        <CKEditor
            editor={Editor}
            config={editorConfiguration}
            data={data}
            onReady={onReady}
            onChange={onChange}
            onBlur={onBlur}
            onFocus={onFocus} />
    )
}

E a página do Editor ficou assim:

import Head from 'next/head'
import dynamic from 'next/dynamic'
import { useState } from 'react'

const CustomEditor = dynamic(() => import('../components/CustomEditor'), { ssr: false })

import styles from '../styles/Home.module.scss'

export default function Editor() {
    const [contents, setContents] = useState('')

    const handleReady = (editor) => {
        // console.log('onReady')
    }

    const handleChange = (event, editor) => {
        // console.log('onChange')
        const data = editor.getData()
        setContents(data)
    }

    const handleBlur = (event, editor) => {
        // console.log('onBlur')
    }

    const handleFocus = (event, editor) => {
        // console.log('onFocus')
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Custom CKEditor Next</title>
                <meta name="description" content="Custom CKEditor Next" />
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <h1>Custom CKEditor Next</h1>
            <CustomEditor data={contents} onReady={handleReady} onChange={handleChange} onBlur={handleBlur} onFocus={handleFocus} />
            <div dangerouslySetInnerHTML={{ __html: contents }} />
        </div>
    )
}

Eu coloquei esse exemplo no meu GitHub, nesse link Custom CKEditor Next

Espero que eu tenha ajudado.

Você deve fazer log-in para responder a esta pergunta.

Esta não é a resposta que você está procurando? Pesquise outras perguntas com a tag .