CRUD를 작성할 때 꼭 없어서는 안될 텍스트 에디터는 다양한 종류가 있다.
그 중에서 Draft.js를 리액트에서 사용할 수 있도록 적용해본다.
크게 Install, write & Edit, view로 구분할 수 있다.
npm i react-draft-wysiwyg draft-js
useState로 상태 관리를 하게 된다.
EditorState.createEmpty()로 초기값을 설정.
에디터를 감싸는 div의 스타일을 원하는 대로 변경하면 된다.
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import { EditorState } from 'draft-js';
const editorStyle = {
cursor: "pointer",
width: "100%",
minHeight: "20rem",
border: "2px solid rgba(209, 213, 219, var(--tw-border-opacity))",
};
.
.
.
.
.
const [editorState, setEditorState] = useState(EditorState.createEmpty());
const onEditorStateChange = (editorState) => {
// editorState에 값 설정
setEditorState(editorState);
};
return (
<div style={editorStyle}>
<Editor
wrapperClassName="wrapper-class"
editorClassName="editor"
toolbarClassName="toolbar-class"
toolbar={{
// inDropdown: 해당 항목과 관련된 항목을 드롭다운으로 나타낼것인지
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true },
history: { inDropdown: false },
}}
placeholder="내용을 작성해주세요."
// 한국어 설정
localization={{
locale: 'ko',
}}
// 초기값 설정
editorState={editorState}
// 에디터의 값이 변경될 때마다 onEditorStateChange 호출
onEditorStateChange={onEditorStateChange}
/>
</div>
);
만약 수정 모드를 사용하고 싶다면 다음과 같이 기존 데이터(info.content
)가 존재할 때 변환시켜서 사용할 수 있다.
useEffect(() => {
const blocksFromHtml = htmlToDraft(info.content);
if (blocksFromHtml) {
const { contentBlocks, entityMap } = blocksFromHtml;
const contentState = ContentState.createFromBlockArray(
contentBlocks,
entityMap
);
const editorState = EditorState.createWithContent(contentState);
setEditorState(editorState);
}
}, []);
리액트에서 html text를 div에 넣어 사용하고 싶을 때 다음과 같이 사용한다.
<div>
<div
dangerouslySetInnerHTML={{ __html: info.content }}
></div>
</div>
여기서 중요한 것은,
draft.js에서 Enter를 누르게 되면, p 태그로 닫히게 되고, 여러번 칠 수록 빈 p 태그가 나타나게 되는데, 이를 엔터로 인식하지 못한다.
에디터에서는 엔터를 많이 쳤다고 해도, view에서는 그만큼 인식이 되지 않는 것이다.
Shift + Enter
를 입력하게 되면 </br>
가 입력되기는 하지만, 현재 Shift + Enter 를 사용할 때에 에러가 나타나고 있기 때문에, 나는 여기서 <p></p>
라는 텍스트 부분을 </br>
로 바꾸는 방법을 사용했다.
const _text = info.content.replace(/<p><\/p>/gi, "</br>");
참고 사이트
0. https://draftjs.org/
1. https://haranglog.tistory.com/12