현재 진행하는 프로젝트에서 마크다운(markdown)을 표시해야 하는 작업이 생겨 react-md-editor 라이브러리를 사용하였는데, 이를 사용하면서 공부한 내용을 기록하고자 한다.
먼저, @uiw/react-md-editor를 설치한다.
npm install @uiw/react-md-editor
또는
yarn add @uiw/react-md-editor
기본적인 Markdown 편집기를 사용하려면 다음과 같이 컴포넌트를 렌더링한다.
import React, { useState } from 'react';
import MDEditor from '@uiw/react-md-editor';
function App() {
const [value, setValue] = useState("**Hello world!!!**");
return (
<div className="container">
<MDEditor value={value} onChange={setValue} />
</div>
);
}
export default App;
기본으로 MDEditor을 생성하면 좌측에 편집md창, 우측에 결과창이 나오는데, 미리보기는 MDEditor안에 있는 Markdown을 꺼내서 결과창만 볼 수 있다. (편집하는 부분이 없기에 source가 필수임.)
import React from 'react';
import MDEditor from '@uiw/react-md-editor';
function App() {
const markdown = `
### Preview Markdown
\`\`\`jsx
import React from "react";
import ReactDOM from "react-dom";
import MDEditor from '@uiw/react-md-editor';
export default function App() {
return (
<div className="container">
<MDEditor.Markdown source="Hello Markdown!" />
</div>
);
}
\`\`\`
`;
return (
<div className="container">
<MDEditor.Markdown source={markdown} />
</div>
);
}
export default App;
data-color-mode 속성을 통해 테마를 변경할 수 있다.(light, dark 지원)
이 속성은 MDEditor나 MDEditor.Markdown의 props에 직접 넣을 수 없고, 이를 감싸고 있는 태그(여기서는 div)의 속성에 설정해주어야 한다.
import React, { useState } from 'react';
import MDEditor from '@uiw/react-md-editor';
function App() {
const [value, setValue] = useState("**Hello world!!!**");
return (
<>
<div className="container" data-color-mode="light">
<MDEditor value={value} onChange={setValue} />
</div>
<div className="container" data-color-mode="dark">
<MDEditor value={value} onChange={setValue} />
</div>
</>
);
}
export default App;
사용자 정의 명령어를 추가하여 원하는 기능을 속성 안에 포함시킬 수도 있는데, 이 때는 command props로 넘겨주면 된다.
import React, { useState } from 'react';
import MDEditor, { commands } from '@uiw/react-md-editor';
function App() {
const [value, setValue] = useState("**Hello world!!!**");
const customCommand = {
name: 'custom',
keyCommand: 'custom',
buttonProps: { 'aria-label': 'Custom command' },
icon: <span>Custom</span>,
execute: (state, api) => {
const modifyText = `~~${state.selectedText}~~`;
api.replaceSelection(modifyText);
},
};
return (
<div className="container">
<MDEditor
value={value}
onChange={setValue}
commands={[...commands.getCommands(), customCommand]}
/>
</div>
);
}
export default App;
위의 사용자 정의 명령을 통해서 이미지 업로드 기능을 추가할 수도 있다.
import React, { useState } from 'react';
import MDEditor, { commands } from '@uiw/react-md-editor';
function App() {
const [value, setValue] = useState("**Hello world!!!**");
const customImageCommand = {
name: 'image',
keyCommand: 'image',
buttonProps: { 'aria-label': 'Insert image' },
icon: <span>Image</span>,
execute: (state, api) => {
const imageURL = prompt('Enter the image URL');
if (imageURL) {
const modifyText = ``;
api.replaceSelection(modifyText);
}
},
};
return (
<div className="container">
<MDEditor
value={value}
onChange={setValue}
commands={[...commands.getCommands(), customImageCommand]}
/>
</div>
);
}
export default App;
사실 이 라이브러리를 사용하게 된 가장 큰 이유는 코드에 대한 하이라이트를 표시하기 위해서였는데, 보통 노션이나 다른 md파일에서 쓰던대로 코드를 작성하니 syntax highlight가 작동하질 않았다. 그 이유는 ```를 그대로 쓰는 것이 아니라,
\`\`\`(언어 종류) (코드) \`\`\`
와 같은 식으로 source 내에 입력해주어야 한다
import React from 'react';
import MDEditor from '@uiw/react-md-editor';
function App() {
const markdown = `
### Code Highlight
\`\`\`javascript
function add(a, b) {
return a + b;
}
\`\`\`
`;
return (
<div className="container">
<MDEditor.Markdown source={markdown} />
</div>
);
}
export default App;
사실 @uiw/react-md-editor를 사용하기 전에, react-markdown과 react-syntax-highlight와 remark-gfm를 세트로 사용하였는데, 해결하지 못한 오류 발생으로 라이브러리를 바꾸게 되었다. 기회가 된다면 이 3개 세트를 기억에 남겨두고 react-md-editor와 비교하는 시간을 가지면 좋겠다.