如何在 react-markdown 中使用自定义组件
How to use custom components in react-markdown
上下文:我有一个 Next.js site with Chakra UI。我有一些用户提供的降价内容,这些内容是在运行时从外部来源(例如,GitHub README.md
用于回购)获取的。
现在,默认情况下,react-markdown (based on remarkjs) uses the HTML <img>
tag for markdown images (![]()
). I want to use the new <Image />
component released in Next.js 10 在用户中提供降价。另外,我也想用相应的 Chakra UI 组件替换其他标签。
我该怎么做?
解决方案
// utils/parser.tsx
import Image from 'next/image';
export default function ImageRenderer({ src, alt }) {
return <Image src={src} alt={alt} unsized />;
}
然后在需要的页面中:
//pages/readme.tsx
import ReactMarkdown from 'react-markdown';
import imageRenderer from '../utils/parser';
// `readme` is sanitised markdown that comes from getServerSideProps
export default function Module({ readme }) {
return <ReactMarkdown allowDangerousHtml={true} renderers={{ image: imageRenderer }} children={readme} />
}
其他元素相同...
react-markdown 允许您定义自己的渲染器。我最近做了类似的事情。我想使用 figure 和 figurecaption 元素。所以,我创建了自己的图像渲染器反应组件。
组件
export default function ImageRenderer(props) {
const imageSrc = props.src;
const altText = props.alt;
return (
<figure className="wp-block-image size-large is-resized">
<img
data-loading="lazy"
data-orig-file={imageSrc}
data-orig-size="1248,533"
data-comments-opened="1"
data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}"
data-image-title="builtin_vs_dotnetwarp"
data-image-description=""
data-medium-file={imageSrc + "?w=300"}
data-large-file={imageSrc + "?w=750"}
src={imageSrc + "?w=10241"}
alt={altText}
srcSet={imageSrc + "?w=1024 1024w, " + imageSrc + "?w=705 705w, " + imageSrc + "?w=150 150w, " + imageSrc + "?w=300 300w, " + imageSrc + "?w=768 768w, " + imageSrc + "?1248w"}
sizes="(max-width: 707px) 100vw, 707px" />
<figcaption style={{ textAlign: "center" }}>{altText}</figcaption>
</figure>
);
}
我使用的渲染器如下
<ReactMarkdown source={blogResponse.data.content} escapeHtml={false} renderers={{ "code": CodeBlockRenderer, "image": ImageRenderer }} />
renderers={{ "code": CodeBlockRenderer, "image": ImageRenderer }} 是你提到自定义渲染器的地方。
上下文:我有一个 Next.js site with Chakra UI。我有一些用户提供的降价内容,这些内容是在运行时从外部来源(例如,GitHub README.md
用于回购)获取的。
现在,默认情况下,react-markdown (based on remarkjs) uses the HTML <img>
tag for markdown images (![]()
). I want to use the new <Image />
component released in Next.js 10 在用户中提供降价。另外,我也想用相应的 Chakra UI 组件替换其他标签。
我该怎么做?
解决方案
// utils/parser.tsx
import Image from 'next/image';
export default function ImageRenderer({ src, alt }) {
return <Image src={src} alt={alt} unsized />;
}
然后在需要的页面中:
//pages/readme.tsx
import ReactMarkdown from 'react-markdown';
import imageRenderer from '../utils/parser';
// `readme` is sanitised markdown that comes from getServerSideProps
export default function Module({ readme }) {
return <ReactMarkdown allowDangerousHtml={true} renderers={{ image: imageRenderer }} children={readme} />
}
其他元素相同...
react-markdown 允许您定义自己的渲染器。我最近做了类似的事情。我想使用 figure 和 figurecaption 元素。所以,我创建了自己的图像渲染器反应组件。
组件
export default function ImageRenderer(props) {
const imageSrc = props.src;
const altText = props.alt;
return (
<figure className="wp-block-image size-large is-resized">
<img
data-loading="lazy"
data-orig-file={imageSrc}
data-orig-size="1248,533"
data-comments-opened="1"
data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}"
data-image-title="builtin_vs_dotnetwarp"
data-image-description=""
data-medium-file={imageSrc + "?w=300"}
data-large-file={imageSrc + "?w=750"}
src={imageSrc + "?w=10241"}
alt={altText}
srcSet={imageSrc + "?w=1024 1024w, " + imageSrc + "?w=705 705w, " + imageSrc + "?w=150 150w, " + imageSrc + "?w=300 300w, " + imageSrc + "?w=768 768w, " + imageSrc + "?1248w"}
sizes="(max-width: 707px) 100vw, 707px" />
<figcaption style={{ textAlign: "center" }}>{altText}</figcaption>
</figure>
);
}
我使用的渲染器如下
<ReactMarkdown source={blogResponse.data.content} escapeHtml={false} renderers={{ "code": CodeBlockRenderer, "image": ImageRenderer }} />
renderers={{ "code": CodeBlockRenderer, "image": ImageRenderer }} 是你提到自定义渲染器的地方。