React 如何展示Markdown内容
需要安装的依赖
根据您提供的React实现代码,您需要安装以下依赖:
npm install react-markdown katex remark-math remark-breaks rehype-katex remark-gfm react-syntax-highlighter
或使用yarn:
yarn add react-markdown katex remark-math remark-breaks rehype-katex remark-gfm react-syntax-highlighter
各依赖的作用
react-markdown: 核心Markdown渲染库katex: 数学公式渲染引擎remark-math: 处理Markdown中的数学公式remark-breaks: 支持Markdown中的换行rehype-katex: 将数学表达式转换为KaTeX渲染remark-gfm: 支持GitHub风格Markdown(表格、任务列表等)react-syntax-highlighter: 代码语法高亮
组件实现
import ReactMarkdown from 'react-markdown'
import 'katex/dist/katex.min.css'
import RemarkMath from 'remark-math'
import RemarkBreaks from 'remark-breaks'
import RehypeKatex from 'rehype-katex'
import RemarkGfm from 'remark-gfm'
import SyntaxHighlighter from 'react-syntax-highlighter'
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
export function Markdown(props: { content: string }) {
return (
<div className="markdown-body">
<ReactMarkdown
remarkPlugins={[RemarkMath, RemarkGfm, RemarkBreaks]}
rehypePlugins={[
RehypeKatex,
]}
components={{
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
return (!inline && match)
? (
<SyntaxHighlighter
{...props}
children={String(children).replace(/\n$/, '')}
style={atelierHeathLight}
language={match[1]}
showLineNumbers
PreTag="div"
/>
)
: (
<code {...props} className={className}>
{children}
</code>
)
},
}}
linkTarget={'_blank'}
>
{props.content}
</ReactMarkdown>
</div>
)
}
如何使用组件
1. 在组件中导入并使用
import React from 'react';
import { Markdown } from './path/to/Markdown';
function App() {
const markdownContent = `
# 这是一个标题
这是普通文本内容
## 代码示例
\`\`\`javascript
const hello = "world";
console.log(hello);
\`\`\`
## 数学公式
$E = mc^2$
## 表格
| 姓名 | 年龄 |
| ---- | ---- |
| 张三 | 20 |
| 李四 | 25 |
`;
return (
<div className="app">
<h1>Markdown预览</h1>
<Markdown content={markdownContent} />
</div>
);
}
export default App;
2. 添加CSS样式
您需要确保已加载KaTeX的CSS样式。在您的主入口文件(如index.js或App.js)中导入:
import 'katex/dist/katex.min.css';
另外,您可能需要添加一些基本的Markdown样式。建议添加类似GitHub的Markdown样式:
npm install github-markdown-css
然后在入口文件中导入:
import 'github-markdown-css/github-markdown.css';
3. 组件功能说明
您提供的Markdown组件具有以下功能:
- 支持基本Markdown语法(标题、列表、加粗、斜体等)
- 支持数学公式(通过KaTeX渲染)
- 支持代码语法高亮(使用atelierHeathLight主题)
- 支持GitHub风格Markdown(表格、任务列表等)
- 链接自动在新标签页中打开
- 支持换行转换
4. 定制组件
如果需要修改代码高亮主题,可以从react-syntax-highlighter/dist/esm/styles/hljs导入其他主题:
import { docco, github, monokai } from 'react-syntax-highlighter/dist/esm/styles/hljs';
然后在SyntaxHighlighter组件中使用:
<SyntaxHighlighter
style={github} // 更改主题
language={match[1]}
showLineNumbers
PreTag="div"
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
完整使用示例
// App.js
import React, { useState } from 'react';
import { Markdown } from './components/Markdown';
import 'katex/dist/katex.min.css';
import './App.css';
function App() {
const [markdownText, setMarkdownText] = useState(`# React Markdown 演示
这是一个简单的 **Markdown** 渲染示例。
## 代码示例
\`\`\`javascript
function greeting(name) {
return \`Hello, \${name}!\`;
}
console.log(greeting("React"));
\`\`\`
## 数学公式
行内公式: $E = mc^2$
独立公式:
$$
\\frac{\\partial f}{\\partial x} = \\lim_{h \\to 0} \\frac{f(x+h) - f(x)}{h}
$$
## 表格
| 功能 | 支持 |
|------|------|
| 表格 | ✅ |
| 代码高亮 | ✅ |
| 数学公式 | ✅ |
| 自动换行 | ✅ |
`);
return (
<div className="app-container">
<div className="editor-section">
<h2>Markdown 编辑器</h2>
<textarea
value={markdownText}
onChange={(e) => setMarkdownText(e.target.value)}
className="markdown-editor"
/>
</div>
<div className="preview-section">
<h2>预览结果</h2>
<div className="preview-container">
<Markdown content={markdownText} />
</div>
</div>
</div>
);
}
export default App;
/* App.css */
.app-container {
display: flex;
height: 100vh;
padding: 20px;
box-sizing: border-box;
}
.editor-section, .preview-section {
flex: 1;
padding: 0 15px;
}
.markdown-editor {
width: 100%;
height: calc(100vh - 100px);
padding: 15px;
font-family: monospace;
font-size: 14px;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
}
.preview-container {
border: 1px solid #eee;
border-radius: 4px;
padding: 20px;
height: calc(100vh - 100px);
overflow: auto;
background-color: white;
}
/* 为markdown-body类添加基本样式 */
.markdown-body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
color: #24292e;
line-height: 1.6;
}
.markdown-body code:not([class*="language-"]) {
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
background-color: rgba(27, 31, 35, 0.05);
border-radius: 3px;
padding: 0.2em 0.4em;
}
.markdown-body pre {
margin: 1em 0;
}
通过这个示例,您可以创建一个完整的Markdown编辑和预览应用程序,用户可以在左侧输入Markdown文本,右侧实时显示渲染后的结果。
性能优化建议
如果您的应用需要处理大量Markdown内容,可以考虑以下优化措施:
- 使用
React.memo包装Markdown组件 - 在textarea输入时使用防抖处理
- 对于非常大的文档,考虑使用虚拟滚动
祝您的Markdown实现顺利!