Toast UI Editor

Tony·2022년 12월 29일
0

react

목록 보기
57/86
post-custom-banner

Toast UI Editor 사용

  • react에서 tui editor를 사용하려면 wrapper 패키지인

@toast-ui/react-editor 만 설치하고 사용 가능하다

사용방법은 공식문서에 나온 것을 그대로 따라하면 된다

이슈

변경된 값을 실시간으로 state로 저장하기

  • onChange에서 전달되는 event 파라미터 또는 어딘가에 value를 저장할 수 있을 줄 알았으나 ref를 등록해서 onChange에서 getInstance().getHtml()로 가져오는 이상한 방식을 사용해서 가져와야 했다
    • 이 부분은 아직 내가 잘 모르는 것일 지도 모르지만 제공되는 on 이 포함된 함수의 모든 event는 EditType("wysiwyg" | "markdown") 이 전달되었다
  • 구글 검색해서 어떤 블로그에서 해결한 방법으로 onChange에서 editor에 있는 html을 state에 저장할 수 있었다
  • 참고 : https://leego.tistory.com/entry/React-%EC%97%90%EB%94%94%ED%84%B0%EB%A1%9C-TOAST-UI-Editor-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0
const onChange = () => {
    const editorHtml = editorRef.current!.getInstance().getHTML();
    setHtml(editorHtml);
  };

<Editor
  ref={editorRef as React.LegacyRef<Editor>}
  initialValue={html}
  previewStyle="vertical"
  height="100%"
  initialEditType="wysiwyg"
  useCommandShortcut
  plugins={[colorSyntax]}
  toolbarItems={[['heading', 'bold']]}
  onChange={onChange}
  hideModeSwitch
  />

ref 타입이 맞지 않는 문제

import { Editor, Viewer } from '@toast-ui/react-editor';

라이브러리에서 가져오는 Editor는 클래스이다
그래서 인지 함수컴포넌트에서 사용하는 useRef와 타입이 잘 맞지 않는 문제가 있었다
그래서 강제로 타입 캐스팅을 해서 맞춰주었다

<Editor
  ref={editorRef as React.LegacyRef<Editor>}
  // ...
  />

컴포넌트에서 editor의 html 보여주기

  • 라이브러리에서 Viewer 라는 컴포넌트를 제공한다
    • innerHtml을 해주는 컴포넌트로 추측된다
  • 제공되는 Viewer를 써서 에디터에서 가져온 html을 Viewer로 보여줄 수 있다

변경 가능한 컴포넌트 만들기

  • 저작도구를 만들어야 하므로 클릭 시 해당 컴포넌트를 수정할 수 있게 하고 싶었다
  • 그리고 다른 컴포넌트를 클릭하면 수정가능한 클릭된 컴포넌트로 변경되고 배경을 클릭하면 수정화면이 사라지는 것을 구현하고 싶었다

const ToastUiEditor = () => {
  const [focusedComponentId, setFocusedComponentId] = React.useState<string>('');
  const handleClickComponent = (id: string) => {
    setFocusedComponentId(id);
  };

  // const handleClickBackground = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {

  return (
    // CustomCommonLayout click event가 정확히 일치하는 경우에만 발생한다
    <CustomCommonLayout
      onClick={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
        if (e.target === e.currentTarget) {
          setFocusedComponentId('');
        }
      }}
    >
      <EditCard
        id="card-1"
        isEditorMode={focusedComponentId === 'card-1'}
        handleClickComponent={handleClickComponent}
      />
      <EditCard
        id="card-2"
        isEditorMode={focusedComponentId === 'card-2'}
        handleClickComponent={handleClickComponent}
      />
    </CustomCommonLayout>
  );
};
  • 페이지에서 현재 관심있는 컴포넌트가 어떤 것인지 하나의 상태를 만들어서 해당 컴포넌트 id와 클릭된 컴포넌트 id가 같으면 수정할 수 있는 모드로 변경하도록 구현했다
  • 만약 배경을 클릭하면 id를 빈스트링("")을 넣어서 모든 컴포넌트가 수정모드가 아니게 되도록 구현해보았다
  • 이 방법보다 좋은 방법이 있으면 해당 방법을 적용할 수 있으면 좋을 것 같다
    • 현재는 강제로 아이디를 넣어줘야 하는데 컴포넌트에 아이디 부여를 어떻게 동적으로 할지는 고민해볼 필요가 있는 것 같다

구현 소스

profile
움직이는 만큼 행복해진다
post-custom-banner

0개의 댓글