Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 오픈소스
- 백준13549번
- 변수
- post
- js
- 파이프라인
- API
- 리액트
- 프로그래머스
- 깃허브
- 자바스크립트
- 백준13549번js
- 백준18111번js
- 리팩토링
- 좋아요추가
- 자바
- Node.js
- npm
- 웹
- 깃
- 예외처리
- 백준18111번
- 타입스크립트
- 컴퓨터공학
- 객체
- 데이터베이스
- gui
- 브랜치
- Express
- CS
Archives
- Today
- Total
Nevertheless
[React 18 , TS] Toast-ui 사용하기 본문
게시물 작성 페이지 : Editor.tsx
TS 에서 props 인터페이스 정의
interface TuiEditorProps {
onChange?: (value: string) => void;
value?: string;
}
- onChange: 에디터 내용이 변경될 때 호출되는 콜백 함수, 문자열 파라미터를 받고 반환값이 없는(void) 함수 타입, 물음표(?) 는 이 prop 이 선택적임을 나타낸다.
- value: 에디터에 표시될 초기 텍스트 값, 문자열 타입이며 선택적 prop 이다.
const TuiEditor = forwardRef<Editor, TuiEditorProps>((props, ref) => {
const { onChange } = props;
...
)
});
컴포넌트를 forwardRef 로 감싸서 상위 컴포넌트에서 감싸서 상위 컴포넌트에서 ref 를 전달 받을 수 있게 한다.
forwardRef<참조할_컴포넌트_타입, props_타입>
- Editor: ref가 가리킬 수 있는 대상의 타입
- TuiEditorProps: 컴포넌트가 받을 수 있는 props의 타입
- props: 일반적인 속성들 (onChange, value 등)
- ref: 에디터 인스턴스를 직접 조작할 수 있게 해주는 참조값
const { onChange } = props; //props 에서 onChange 함수를 구조분해 할당으로 추출
useEffect(() => {
if ((ref as any)?.current) { // ref.current 가 존재하는지 확인
const instance = (ref as any).current.getInstance(); // toast ui editor 의 인스턴스 가져오기
//에디터의 내용이 변경될 때마다 실행될 이벤트 리스너 등록
instance.on('change', () => {
if (onChange) { //onChange prop이 존재하는 경우에만 실행
onChange(instance.getHTML()); // 현재 에디터의 HTML 내용을 가져와서 OnChange 함수에 전달
}
});
}
}, [onChange, ref]); //onChange 나 ref 가 변경될 때마다 useEffect 재실행
- ref as any를 사용하는 이유는 TypeScript의 엄격한 타입 검사를 우회하기 위함
- getInstance()는 Toast UI Editor의 메서드로, 단순히 에디터에 작성된 내용만을 의미하는 것이 아니라, 에디터의 핵심 기능들을 조작할 수 있는 인스턴스를 반환하는 메서드이다.
- instance.on('change', ...)는 에디터 내용이 변경될 때마다 콜백 함수를 실행하도록 이벤트 리스너를 설정
- instance.getHTML()은 현재 에디터에 작성된 내용을 HTML 형식으로 반환
return (
<Box display="flex" justifyContent="center" width="100%">
<Box width="75%">
<Editor
//Editor 컴포넌트에 대한 참조를 생성,컴포넌트 외부에서 Editor 의 메서드들을 직접 호출할 수 있음
ref={ref}
height="500px" // 높이
placeholder="Please Enter Text."
previewStyle="tab" // 미리 보기 방식
initialEditType="wysiwyg" // 초기 편집 타입
toolbarItems={[ // 에디터 툴바에 표시될 도구들을 그룹별로 설정
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task', 'indent', 'outdent'],
['table', 'image', 'link'],
['code', 'codeblock'],
]}
initialValue={props.value || " "} // 초기 내용 설정, 값이 없을 경우 공백
usageStatistics={false} // 사용 통계 수집 비활성화
plugins={[[colorSyntax, colorSyntaxOptions],fontSize]} // 색상 구문과 글꼴 크기 플러그인 활성화
/>
</Box>
</Box>
)
💡전체 코드
// Editor.tsx
import '@toast-ui/editor/dist/toastui-editor.css'
import { Editor } from '@toast-ui/react-editor'
import React, { forwardRef, useEffect } from 'react'
import 'tui-color-picker/dist/tui-color-picker.css'
import '@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css'
import colorSyntax from '@toast-ui/editor-plugin-color-syntax'
import fontSize from "tui-editor-plugin-font-size";
import "tui-editor-plugin-font-size/dist/tui-editor-plugin-font-size.css";
import { Box } from '@mui/material'
interface TuiEditorProps {
onChange?: (value: string) => void;
value?: string;
}
const colorSyntaxOptions = {
preset: [
'#333333', '#666666', '#FFFFFF', '#EE2323',
'#F89009', '#009A87', '#006DD7', '#8A3DB6',
'#781B33', '#5733B1', '#953B34', '#FFC1C8',
'#FFC9AF', '#9FEEC3', '#99CEFA', '#C1BEF9',
],
}
const TuiEditor = forwardRef<Editor, TuiEditorProps>((props, ref) => {
const { onChange } = props;
useEffect(() => {
if ((ref as any)?.current) {
const instance = (ref as any).current.getInstance();
instance.on('change', () => {
if (onChange) {
onChange(instance.getHTML());
}
});
}
}, [onChange, ref]);
return (
<Box display="flex" justifyContent="center" width="100%">
<Box width="75%">
<Editor
ref={ref}
height="500px"
placeholder="Please Enter Text."
previewStyle="tab"
initialEditType="wysiwyg"
toolbarItems={[
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task', 'indent', 'outdent'],
['table', 'image', 'link'],
['code', 'codeblock'],
]}
initialValue={props.value || " "} // Add value prop support
usageStatistics={false}
plugins={[[colorSyntax, colorSyntaxOptions],fontSize]}
/>
</Box>
</Box>
)
});
export default TuiEditor;