reactjs - 如何在 HTML 字符串中插入一个 React 组件,然后使用 dangerouslySetInnerHTML 渲染它?
问题描述
我正在使用 NextJs。我有一个从服务器获取的 html 字符串。它代表一篇博文并包含多个<img>
标签。我目前正在渲染这样的帖子:
const blogpostHtml = "..." // an html string that comes from the server
return (
...
<div
dangerouslySetInnerHTML={{__html: blogpostHtml}}
/>
...
)
它工作正常。但是,我想为图像添加功能。我发现这个库用一个不受控制的组件完成了我想要的:
...
<Zoom>
<img
alt="some alt"
width="500"
src="the image url"
/>
</Zoom>
...
但是,我注意到我不能简单地插入Zoom
标签,因为它被解释为原始 html 标签而不是组件。如果我尝试将它呈现为字符串,它就会失去功能。
let html = ReactDOMServer.renderToString(
<Zoom>
<img
alt="some alt"
width="500"
src="the image url"
/>
</Zoom>
)
return (
...
<div
dangerouslySetInnerHTML={{__html: html}}
/>
...
)
正如您在图像中看到的,生成的 html 与按预期使用 Zoom 组件相同,但按钮丢失了它的事件
那么如何将来自服务器的 html 字符串和不受控制的 Zoom 组件结合起来来实现我想要的呢?
解决方案
感谢威廉在评论中的回答,我得到了这个解决方案
import Zoom from 'react-medium-image-zoom'
import ReactDOM from 'react-dom'
import { useEffect } from 'react'
const Index = () => {
const html = `
<p>This is some text</p>
<img src="some-img-src.jpg"/>
<p>More text here</p>
`
useEffect(() => {
// 1. extract imgs and src
const imgs = document.getElementsByTagName('img')
const srcArray = Array.from(imgs).map(img => img.src)
// 2. wrap images with div then replace each div using ReactDOM.render
for (let i = 0; i < imgs.length; i++) {
const wrapper = document.createElement('div')
wrapper.setAttribute('id', `img-${i}`)
imgs[i].parentNode.insertBefore(wrapper, imgs[i])
wrapper.appendChild(imgs[i])
ReactDOM.render(
<Zoom>
<img src={srcArray[i]} />
</Zoom>,
document.querySelector(`#img-${i}`)
)
}
}, [])
return (
<>
<div
dangerouslySetInnerHTML={{
__html: html
}}
/>
</>
)
}
export default Index
推荐阅读
- java - 如何将 HttpsURLConnection GET 更改为 POST 请求?
- javascript - 如何根据 Tabulator-Dash 中的某些条件以编程方式选择行
- python - 从 nasdaq 下载所有带有 json 文件链接的列表
- python - VS Code 集成终端在运行 matplotlib 脚本时显示 Qt 不兼容
- coq - 结合隐式参数和部分应用
- python - 从本地另一个烧瓶应用程序调用烧瓶应用程序
- r - 用户应该能够指定产品(黄金)和时间段(每年或每月),并且该功能应该自动接受这些输入
- python - 如何使用包含文本和数字的单元格计算包含特定范围内数字的单元格
- java - while循环中的切换函数只给出相同的答案
- react-native - 当应用程序关闭时,有什么方法可以在 react-native 中执行某些操作吗?