Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use react Editor using a functional component? #3262

Open
DNA-PC opened this issue Aug 14, 2024 · 1 comment
Open

How to use react Editor using a functional component? #3262

DNA-PC opened this issue Aug 14, 2024 · 1 comment
Labels

Comments

@DNA-PC
Copy link

DNA-PC commented Aug 14, 2024

https://github.com/nhn/tui.editor/tree/master/apps/react-editor

There are only classes examples, not functional components (which is the default now)

More specifically, I'm interested about how to be notified of content changes events

@DNA-PC
Copy link
Author

DNA-PC commented Aug 14, 2024

Here is one implementation that works and is compatible with SSR (SSR disabled, but avoids crashing)

import React, { useEffect, useRef } from "react"
import "@toast-ui/editor/dist/toastui-editor.css"
import { Editor, EditorProps } from "@toast-ui/react-editor"

// Extend EditorOptions and customize the necessary props
interface MarkdownEditorProps extends EditorProps {
  onContentChange?: (value: string) => void
}

const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
  onContentChange, // Capture the onContentChange handler
  ...rest // Capture the rest of the EditorOptions props
}) => {
  const editorRef = useRef<any>(null)

  useEffect(() => {
    const handleChange = () => {
      const editorInstance = editorRef.current?.getInstance()
      if (editorInstance && onContentChange) {
        const markdown = editorInstance.getMarkdown()
        onContentChange(markdown)
      }
    }

    const editorInstance = editorRef.current?.getInstance()

    if (editorInstance) {
      editorInstance.on("change", handleChange)
    }

    // Cleanup listener on component unmount
    return () => {
      if (editorInstance) {
        editorInstance.off("change", handleChange)
      }
    }
  }, [onContentChange])

  return (
    <div style={{ display: "flex" }}>
      <div style={{ flex: 1, width: "100%" }}>
        <Editor
          // @ts-ignore
          ref={editorRef}
          useCommandShortcut={true}
          {...rest} // Spread other EditorOptions props
        />
      </div>
    </div>
  )
}

export default MarkdownEditor
"use client"

import dynamic from "next/dynamic"
import React from "react"
import { useRecoilState } from "recoil"
import { activeEmbedContentState } from "app/modules/embed/states/embedPropsState"

// Dynamically import the Editor component from @toast-ui/react-editor
const MarkdownEditor = dynamic(() => import("app/modules/markdownEditor/MarkdownEditor").then((mod) => mod.default), {
  ssr: false, // Disable SSR for this component
})

interface MarkdownEmbedContentEditorProps {}

const MarkdownEmbedContentEditor: React.FC<MarkdownEmbedContentEditorProps> = ({}) => {
  const [activeEmbedContent, setActiveEmbedContent] = useRecoilState(activeEmbedContentState)

  const handleContentChange = (content: string) => {
    setActiveEmbedContent(content) // Update Recoil state whenever content changes
  }

  return (
    <div>
      <MarkdownEditor
        initialValue={activeEmbedContent}
        initialEditType={"wysiwyg"}
        minHeight={"300px"}
        placeholder={`Start typing...`}
        onContentChange={handleContentChange} // Pass the content change handler to the editor
      />
    </div>
  )
}

export default MarkdownEmbedContentEditor

I first tried to dynamically import (to avoid SSR crashing with navigator not defined) in MarkdownEditor, but that caused other issues with useRef which made the whole thing much harder to code (needed to use forwardRef but didn't quite get that, avoided the issue altoghether)

An example in the readme would have been quite helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant