无法在 React 组件中显示从 Showdown 插件生成的 HTML
Unable to display generated HTML ,from Showdown plugin, in React component
我正在使用 Showdown 模块从 markdown 中获取 HTML。我想在我的 React 组件中显示生成的 HTML。我的转换器在生成 HTML 时工作正常:<h1 id="typeyourmarkdownbountyhere">Type your markdown bounty here…</h1>
但我收到此错误消息:Uncaught Error: Target container is not a DOM element.
生成的HTML有没有another/better的显示方式?谁能指出我做错了什么?
import { observer } from "mobx-react-lite"
import React from "react"
import * as ReactDOM from 'react-dom';
import Showdown from 'showdown'
import { useStore } from "../store/Provider"
const converter = new Showdown.Converter({
tables: true,
simplifiedAutoLink: true,
strikethrough: true,
tasklists: true,
})
function Bounties() {
const store = useStore()
return (
store.bounties.map( bounty => (
<div>
<h3 key={bounty.id}>{bounty.title}</h3>
<div id="bountyBody"></div>
{ReactDOM.render(converter.makeHtml(bounty.body), document.getElementById('bountyBody')) }
</div>
))
)
}
export default observer(Bounties)
抛出该错误是因为您试图获取对 DOM 节点的引用,而它仍要在 DOM 本身上呈现。您可以通过在带有空 deps 数组 [] 的 useEffect
中调用 ReactDOM.render
来解决它,这样它将在第一次渲染后执行,但您会注意到它无论如何都不会按预期工作,因为它会呈现一个代表 HTML 代码的字符串,所以它不会解析它! ReactDOM.render
用于将 JSX 代码附加到 DOM 节点,同时您试图传递 HTML 字符串(这就是 converter.makeHtml()
returns)。所以它永远不会起作用。
可行的方法是:
- 将 Markdown 转换为 HTML
- 转译 HTML/JSX 到 React 第一级 API
- 解析转译后的代码
- 作为真正的 JSX 代码执行它
这是一个例子:
import React, { useMemo, useEffect } from 'react';
import Showdown from 'showdown';
const buble = require('buble');
const MarkdownToJSX = ({ md }) => {
if (typeof md !== 'string') return null;
const makeComponent = useMemo(() => {
const converter = new Showdown.Converter({
tables: true,
simplifiedAutoLink: true,
strikethrough: true,
tasklists: true,
});
const html = `<>${converter.makeHtml(md)}</>`;
const code = buble.transform(html).code;
const makeComponent = Function('React', 'return ' + code);
return makeComponent;
}, [md]);
return makeComponent(React);
};
我正在使用 Showdown 模块从 markdown 中获取 HTML。我想在我的 React 组件中显示生成的 HTML。我的转换器在生成 HTML 时工作正常:<h1 id="typeyourmarkdownbountyhere">Type your markdown bounty here…</h1>
但我收到此错误消息:Uncaught Error: Target container is not a DOM element.
生成的HTML有没有another/better的显示方式?谁能指出我做错了什么?
import { observer } from "mobx-react-lite"
import React from "react"
import * as ReactDOM from 'react-dom';
import Showdown from 'showdown'
import { useStore } from "../store/Provider"
const converter = new Showdown.Converter({
tables: true,
simplifiedAutoLink: true,
strikethrough: true,
tasklists: true,
})
function Bounties() {
const store = useStore()
return (
store.bounties.map( bounty => (
<div>
<h3 key={bounty.id}>{bounty.title}</h3>
<div id="bountyBody"></div>
{ReactDOM.render(converter.makeHtml(bounty.body), document.getElementById('bountyBody')) }
</div>
))
)
}
export default observer(Bounties)
抛出该错误是因为您试图获取对 DOM 节点的引用,而它仍要在 DOM 本身上呈现。您可以通过在带有空 deps 数组 [] 的 useEffect
中调用 ReactDOM.render
来解决它,这样它将在第一次渲染后执行,但您会注意到它无论如何都不会按预期工作,因为它会呈现一个代表 HTML 代码的字符串,所以它不会解析它! ReactDOM.render
用于将 JSX 代码附加到 DOM 节点,同时您试图传递 HTML 字符串(这就是 converter.makeHtml()
returns)。所以它永远不会起作用。
可行的方法是:
- 将 Markdown 转换为 HTML
- 转译 HTML/JSX 到 React 第一级 API
- 解析转译后的代码
- 作为真正的 JSX 代码执行它
这是一个例子:
import React, { useMemo, useEffect } from 'react';
import Showdown from 'showdown';
const buble = require('buble');
const MarkdownToJSX = ({ md }) => {
if (typeof md !== 'string') return null;
const makeComponent = useMemo(() => {
const converter = new Showdown.Converter({
tables: true,
simplifiedAutoLink: true,
strikethrough: true,
tasklists: true,
});
const html = `<>${converter.makeHtml(md)}</>`;
const code = buble.transform(html).code;
const makeComponent = Function('React', 'return ' + code);
return makeComponent;
}, [md]);
return makeComponent(React);
};