[React] Markdown 렌더링하기

ksj0314·2024년 6월 28일
0

React

목록 보기
16/27

React는 깃허브 등에서 작성한 마크다운 파일을 파싱하여 렌더링할 수 있습니다.


설치

npm install react-markdown
npm install remark-gfm
npm install react-syntax-highlighter

  • 마크다운 사용을 위해 react-markdown을 설치합니다.
  • github에서는 기존 마크다운에 몇 가지 기능이 추가되어있어 remark-gfm을 설치합니다.
  • 백틱이나 코드블럭등의 경우 react-syntax-highlighter를 설치하여 따로 스타일링이 필요합니다.

마크다운 출력

// JSX
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import SyntaxHighlighter from "react-syntax-highlighter";

function MarkdownComponent(){

	const markdown = `
		## 마크다운 제목2
		#### 마크다운 제목4
	`;

	return(
    	<ReactMarkdown>
        	{markdown}
        </ReactMarkdown>
    );
}
  • 위와 같이 import하면 ReactMarkdown 컴포넌트를 사용해 마크다운 형식의 텍스트로 렌더링됩니다.

.md 파일 렌더링

// JSX
function MarkdownComponent(){

	const [mdnumber, setMdnumber] = useState(0);
	const [markdown, setMarkdown] = useState('');

	const contain = [
        "what_to_eat.md",
        "star.md",
        "cyworld.md",
        "mini-maple.md"
    ];

	useEffect(() => {
        fetch(`./markdown/${contain[mdnumber]}`)
          .then((response) => response.text())
          .then((text) => {
              const formattedText = text.replaceAll("<br/>","\n\n");
              setMarkdown(formattedText);
          });
    }, [mdnumber]);

	return(
    	<ReactMarkdown>
        	{markdown}
        </ReactMarkdown>
    );
}
  • 여러 md 파일을 렌더링하기 위해 파일명을 저장하는 contain 변수를 사용했습니다.
  • fetch()를 사용하여 markdown state에 파일을 텍스트로 변환하여 저장하고 <ReactMarkdown>에 전달합니다.
  • <br/>태그를 사용한 경우 다이렉트로 출력되므로 "\n\n"으로 변환합니다.
  • mdnumber가 변경되는 경우만 렌더링하기 위해 useEffect()를 사용합니다.

  • 마크다운 파일의 경로는 위와 같습니다.

remarkGfm | SyntaxHighlighter

// JSX
~~~
	const renderers = () => {
    	~~~
    };
~~~
    <ReactMarkdown
        remarkPlugins={[remarkGfm]}
        components={renderers} >
        {markdown}
    </ReactMarkdown>
~~~
  • remarkGfmReactMarkdownremarkPlugins 속성에 넣어 사용합니다.
  • SyntaxHighlighter의 경우 components 속성에서 작업이 필요합니다. 위 코드는 가독성을 위해 renderers()을 분리하여 작성되었습니다.

renderers()

// JSX
const renderers = () => {
    code({ node, inline, className, children, ...props }) {
        const match = /language-(\w+)/.exec(className || '');
        return(
            (!inline && match) ?
          	<SyntaxHighlighter
                {...props}
                language={match[1]}
                className = "codeRefer" >
              	{String(children).replace(/\n$/, '')}
            </SyntaxHighlighter> :
          	<SyntaxHighlighter
                {...props}
                className = "backtick" >
              	{String(children)}
            </SyntaxHighlighter>
        );
    }
};
  • 주요 부분을 설명하자면 !inline은 인라인 코드인지 블럭 코드인지 구분하는 구문입니다.
  • 보통 백틱을 사용한 코드는 인라인 코드를 의미하며 삼중 백틱 (코드블럭)은 블럭스타일로 표현됩니다.
  • 위처럼 SyntaxHighlighter을 사용 시 마크다운 중 백틱이나 코드블럭으로 이루어진 부분에 알맞은 className을 부여할 수 있습니다.
  • 해당 className을 이용하여 추가로 스타일링 작업을 진행합니다.

0개의 댓글