使用 ReactDOMServer.renderToString 将 gatsby-image 注入到从 markdown 创建的 html
Injecting gatsby-image into html created from markdown using ReactDOMServer.renderToString
Minimum Reproducible Example on Github
我正在尝试将一些图像插入到我从 markdown 创建的页面中。我正在尝试使用 ReactDomServer.renderToString()
来做到这一点
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<Img fluid={data.allFile.edges[0].node.childImageSharp.fluid} />)
}
})
...
}
img 显示为黑框,如果我右键单击该图像,我可以在新选项卡中打开它,它会显示图像的本来面目。
我之前在第一个 Gatsby 项目中遇到过这个问题。
类似这样的问题chat and the error image issue here.
如果你像他们在上面的频谱聊天中所说的那样替换 GatsbyImageSharpFixed_withWebp_tracedSVG
,或者这是我当前的代码,例如,基本上与 WebP
新图像格式有关。
export const query = graphql`
query {
allImageSharp {
edges {
node {
fluid(maxWidth: 110) {
aspectRatio
originalName
sizes
src
srcSet
srcWebp
tracedSVG
}
}
}
}
}
`;
希望对您有所帮助。
我认为问题可能出在 useEffect
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<MyComponent args={myArgs} />)
}
},[])
...
}
我觉得你应该尝试添加useEffect(()=>{},[]),第二个参数只在组件挂载时刷新图片,没有这个每次都会刷新图片。
我是怎么理解这个问题的
图像html已正确插入页面
gatsby-image
加载最低质量的图像并应用一些内联
样式。所有这些信息都存在于 html) 这样做是为了
启用图像模糊效果以获得更好的用户体验。
从未应用加载更高分辨率图像和删除内联样式的客户端代码。
有用的诊断信息
useEffect
中的函数不会在服务器端获得 运行,而是在组件安装后在客户端获得。可以通过在效果中添加 console.log
语句并查看它是否已记录在浏览器的控制台上来验证这一点。
问题的根源
ReactDOMServer.renderToString()
仅构建组件所需的 HTML,然后它要求组件为 hydrated.
直接修复
- 您可以使用
ReactDOM.render
将图像放在页面上,因为效果将在客户端执行。我有一个 PR 显示 here.
推荐方法
- 您可以改为将图像导入 mdx 组件并直接在那里渲染。你的 gatsby 配置已经可以支持这个在
content/blog/hello-world/index.mdx
中,你可以用这个 ![A salty egg, yummm](./salty_egg.jpg)
替换 injectImage
div(其中 []
中的文本是替代文本)
- 此文档可能会有帮助
希望对您有所帮助!
Minimum Reproducible Example on Github
我正在尝试将一些图像插入到我从 markdown 创建的页面中。我正在尝试使用 ReactDomServer.renderToString()
来做到这一点const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<Img fluid={data.allFile.edges[0].node.childImageSharp.fluid} />)
}
})
...
}
img 显示为黑框,如果我右键单击该图像,我可以在新选项卡中打开它,它会显示图像的本来面目。
我之前在第一个 Gatsby 项目中遇到过这个问题。 类似这样的问题chat and the error image issue here.
如果你像他们在上面的频谱聊天中所说的那样替换 GatsbyImageSharpFixed_withWebp_tracedSVG
,或者这是我当前的代码,例如,基本上与 WebP
新图像格式有关。
export const query = graphql`
query {
allImageSharp {
edges {
node {
fluid(maxWidth: 110) {
aspectRatio
originalName
sizes
src
srcSet
srcWebp
tracedSVG
}
}
}
}
}
`;
希望对您有所帮助。
我认为问题可能出在 useEffect
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<MyComponent args={myArgs} />)
}
},[])
...
}
我觉得你应该尝试添加useEffect(()=>{},[]),第二个参数只在组件挂载时刷新图片,没有这个每次都会刷新图片。
我是怎么理解这个问题的
图像html已正确插入页面
gatsby-image
加载最低质量的图像并应用一些内联 样式。所有这些信息都存在于 html) 这样做是为了 启用图像模糊效果以获得更好的用户体验。从未应用加载更高分辨率图像和删除内联样式的客户端代码。
有用的诊断信息
useEffect
中的函数不会在服务器端获得 运行,而是在组件安装后在客户端获得。可以通过在效果中添加console.log
语句并查看它是否已记录在浏览器的控制台上来验证这一点。
问题的根源
ReactDOMServer.renderToString()
仅构建组件所需的 HTML,然后它要求组件为 hydrated.
直接修复
- 您可以使用
ReactDOM.render
将图像放在页面上,因为效果将在客户端执行。我有一个 PR 显示 here.
推荐方法
- 您可以改为将图像导入 mdx 组件并直接在那里渲染。你的 gatsby 配置已经可以支持这个在
content/blog/hello-world/index.mdx
中,你可以用这个![A salty egg, yummm](./salty_egg.jpg)
替换injectImage
div(其中[]
中的文本是替代文本) - 此文档可能会有帮助
希望对您有所帮助!