React-markdown使用求助:GFM表格渲染异常等三类问题
React-Markdown 使用问题求助
问题描述
我在React中使用react-markdown库渲染Markdown时,遇到2个问题和1个疑问:
- 使用
remark-gfm插件时,表格无法正确渲染。 - 段落间换行不符合预期:输入时在段落间设置5个换行,渲染后仅显示1个换行。
- 渲染后的复选框是否可以修改选中状态?
应用组件代码
1. App.jsx
import "./styles/App.css"; import styled from "styled-components" import MarkedInput from './components/MarkedInput' import Result from "./components/Result"; import { useState } from "react"; import EditorContext from "./EditorContext"; const AppContainer = styled.div` width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; `; const Title = styled.div` font-size: 25px; font-weight: 700; font-family: "Lato", sans-serif; margin-bottom: 1em; `; const EditorContainer = styled.div` width: 100%; height: 100%; display: flex; `; function App() { const [markdownText, setMarkdownText] = useState(""); const contextValue = { markdownText, setMarkdownText }; return ( <EditorContext.Provider value={contextValue}> <AppContainer> <Title>Markdown Editor</Title> <EditorContainer> <MarkedInput /> <Result /> </EditorContainer> </AppContainer> </EditorContext.Provider> ); } export default App;
2. MarkedInput.jsx
import React from "react"; import { useContext } from "react"; import styled from "styled-components"; import EditorContext from "../EditorContext"; const Container = styled.div` width: 50%; height: 100%; padding: 14px; border-right: 1.5px solid rgba(15, 15, 15, 0.4); font-family: "Lato", sans-serif; `; const Title = styled.div` font-size 22px; font-weight: 600; margin-bottom: 1em; padding: 8px 0; border-bottom: 1px solid rgba(15, 15, 15, 0.3); `; const TextArea = styled.textarea` width: 100%; height: 100%; resize: none; border: none; outline: none; font-size: 17px; `; function MarkedInput(props) { const { setMarkdownText } = useContext(EditorContext); const onInputChange = (event) => { const newValue = event.currentTarget.value; setMarkdownText(newValue); }; return ( <Container> <Title>Markdown Text</Title> <TextArea onChange={onInputChange} /> </Container> ); } export default MarkedInput;
3. EditorContext.jsx
import React from 'react' const defaulContext = { markdownText: "", setMarkdownText: () =>{} } export default React.createContext(defaulContext)
4. Result.jsx
import React from "react"; import { useContext } from "react"; import { ReactMarkdown } from "react-markdown/lib/react-markdown"; import styled from "styled-components"; import EditorContext from "../EditorContext"; //import remarkGfm from 'https://esm.sh/remark-gfm@3' import remarkGfm from "remark-gfm"; const Container = styled.div` width: 50%; height: 100%; padding: 13px; font-family: "Lato", sans-serif; `; const Title = styled.div` font-size 22px; font-weight: 600; margin-bottom: 1em; padding: 8px 0; border-bottom: 1px solid rgba(15, 15, 15, 0.3); `; const ResultArea = styled.div` width: 100%; heigth: 100%; border: none; font-size: 17px; `; function Result(props) { const { markdownText } = useContext(EditorContext); return ( <Container> <Title>Converted Text</Title> <ResultArea> <ReactMarkdown children={markdownText} remarkPlugins={[remarkGfm]} ></ReactMarkdown> </ResultArea> </Container> ); } export default Result;
项目依赖
"dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-markdown": "^8.0.5", "remark-gfm": "^3.0.1", "styled-components": "^5.3.10" }
运行环境
- Firefox v112.0.2
- Windows 10 Pro 22H2
问题解答
1. 表格无法正确渲染
首先确认GFM表格语法是否标准,示例:
| 表头1 | 表头2 | |-------|-------| | 内容1 | 内容2 |
当前依赖版本组合是兼容的,若仍未渲染,大概率是缺少表格样式。添加基础CSS样式即可让表格正常显示:
table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; }
2. 段落间换行不符合预期
Markdown标准中,多个连续换行只会被解析为一个段落分隔。解决方式有两种:
- 自定义段落间距:为
<p>标签添加CSS margin,控制段落间距离:
p { margin-bottom: 1.5em; /* 按需调整数值 */ }
- 保留输入换行:安装
remark-breaks插件,将单个换行解析为<br />:- 安装:
npm install remark-breaks - 在
Result.jsx中配置:
import remarkBreaks from 'remark-breaks'; // ... <ReactMarkdown children={markdownText} remarkPlugins={[remarkGfm, remarkBreaks]} /> - 安装:
3. 渲染后的复选框能否修改选中状态
默认渲染的复选框是禁用状态,要实现可交互,需自定义input组件:
在Result.jsx的ReactMarkdown中添加components配置:
<ReactMarkdown children={markdownText} remarkPlugins={[remarkGfm]} components={{ input: ({ checked, ...props }) => ( <input type="checkbox" checked={checked} {...props} onChange={(e) => { // 这里可处理状态变化,若需同步到Markdown文本,需解析内容并更新`markdownText` console.log('复选框状态变更:', e.target.checked); }} /> ) }} />
若要双向同步Markdown内容,需解析原始文本,找到对应任务项修改[x]/[ ]标记,再更新markdownText状态。
内容的提问来源于stack exchange,提问作者Foster
相关产品推荐
相关产品推荐

