react 에서 사용되는 editor libraray 중 하나인 react-draft-wysiwyg 를 typescript 환경에서 어떻게 사용했는지 리뷰 아닌 리뷰 해보려함.
(사실은 나중에 내가 찾아보려고..)
[NPM] https://www.npmjs.com/package/react-draft-wysiwyg
[DEMO] https://jpuri.github.io/react-draft-wysiwyg/#/
- draft-js 를 추가로 설치하는 이유는 DOM 에 해당 텍스트를 넣어줘야 하기 때문.
import { Editor } from "react-draft-wysiwyg";
import { EditorState, convertToRaw } from "draft-js";
- text를 담을 state의 초기값은 EditorState.createEmpty() 로 해줘야 한다. 그래야 Immutable 객체로 나온다.
const [content, setContent] = useState<EditorState>(EditorState.createEmpty());
console.log(content);
// expected
// EditorState: {
// _immutable: {
// ...
// currentContent: {
// ...
// blockMap: {}
// entityMap: {}
// }
// }
// }
<Editor
...some properties...
editorState={content}
/>
const handleSubmit = () => {
// 1. immutable 객체를 getCurrentContent() 함수로 ContentState 로 만들어 준다.
// 2. convertToRaw로 ContentState 의 block 과 entityMap 만 추출해준다.
// 3. blockMap, entityMap 을 string 으로 만들어준다.
const converContent = content instanceof EditorState ? convertToRaw(content.getCurrentContent()) : content;
(async function(){
const response = await fetchApi({
content: JSON.stringify(convertContent);
});
})();
}
console.log(content.getCurrentContent());
// expected
// ContentState: {
// entityMap: {}
// blockMap: {} <-- text string이 있는 객체
// }
console.log(convertToRaw(content.getCurrentContent()))
// expected
// blocks: {}
// entityMap: {}
최종 convertToRaw(content.getCurrentContent()) 에서 return 된 object 를 api 에 실어 보내준다.
import draftToHtml from 'draftjs-to-html';
// https://www.npmjs.com/package/draftjs-to-html
import domPurify from 'dompurify'
// https://www.npmjs.com/package/dompurify
import { EditorState, convertToRaw, getCurrentContent } from "draft-js";
const content = `{"blocks":[{"key":"14vju","text":"ddd","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}`;
const convertedContent = (content: EditorState): string => {
const editorStateToBlocks = content instanceof EditorState ? convertToRaw(content.getCurrentContent()) : content;
return draftToHtml(editorStateToBlocks);
};
// html 로 convert 된 content 를 dompurify 같은 library 로 javascript 같은 코드를 삭제 해준다.
const clean = domPurify.sanitize(convertedContent(content));
// clean 된 dom 을 react component 에 넣어준다.
<SomeComponent dangerouslySetInnerHTML={{__html: clean}} />
const content = `{"blocks":[{"key":"14vju","text":"ddd","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}`;
const [editorContent, setEditorContent] = useState<EditorState>(EditorState.createEmpty());
// 1. Api 에서 가져온 string -> EditorState 로 변환
// 1) 가져온 string 을 JSON.parse 로 JSON 객체로 변환
// 2) convertFromRaw 로 JSON 객체를 ContentState 로 변환
// 3) EditorState.createWithContent 로 EditorState: { _immutable: {} } 로 변환
const convertToEditorState = (content: string) => EditorState.createWithContent(convertFromRaw(JSON.parse(content)));
const editorStateContent = convertToEditorState(content);
// 2. EditorState 에서 Blocks, entityMap 을 추출
// 1) EditorState의 내장함수 getCurrentContent 를 통해 ContentState 추출
// - expected: ContentState: {}
// 2) convertToRaw 로 blocks, entityMap 추출
// - expected: {blocks: [], entityMap: {}}
const blocks = convertToRaw(editorStateContent.getCurrentContent());
const html = draftToHtml(blocks);
... 작성중