【问题标题】:How can I insert a React component inside an HTML string and then render it with dangerouslySetInnerHTML?如何在 HTML 字符串中插入一个 React 组件,然后使用 dangerouslySetInnerHTML 渲染它?
【发布时间】:2020-05-01 00:50:30
【问题描述】:

我正在使用 NextJs。我有一个从服务器获取的 html 字符串。它代表一篇博文,包含几个<img> 标签。我目前正在渲染这样的帖子:

const blogpostHtml = "..." // an html string that comes from the server
return (
  ...
  <div
    dangerouslySetInnerHTML={{__html: blogpostHtml}}
  />
  ...
)

而且效果很好。但是,我想为图像添加功能。我发现 this library 用一个不受控制的组件完成了我想要的:

  ...
  <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组件来实现我想要的呢?

【问题讨论】:

标签: reactjs next.js


【解决方案1】:

感谢威廉在 cmets 中的回答,我得到了这个解决方案

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 2019-11-26
    • 2023-03-25
    相关资源
    最近更新 更多