在React不直接管理DOM的区域中,可以在浏览器中使用ReactDOMServer.renderToString吗?

时间:2016-05-06 19:13:42

标签: reactjs leaflet react-dom

我正在使用Leaflet(通过react-leaflet)开发应用。 Leaflet直接操作DOM。 react-leaflet库不会改变它,它只是为您提供React组件,您可以使用这些组件以反应友好的方式控制Leaflet映射。

在这个应用程序中,我想使用自定义地图标记,这些标记是包含一些简单元素的div。在Leaflet中执行此操作的方法是将标记的icon属性设置为DivIcon,您可以在其中设置自定义HTML。您可以通过将DivIcon的html属性设置为包含HTML的字符串来设置内部HTML。就我而言,我希望从React组件呈现HTML。

为了做到这一点,似乎正确的方法是使用ReactDOMServer.renderToString()将我想要的组件在地图标记内呈现为一个字符串,然后我将其设置为html DivIcon的财产:

MyMarker.js:

import React, { Component } from 'react'
import { renderToString } from 'react-dom/server'
import { Marker } from 'react-leaflet'
import { divIcon } from 'leaflet'

import MarkerContents from './MarkerContents'

export class MyMarker extends Component {
  render() {
    const markerContents = renderToString(<MarkerContents data={this.props.data} />)
    const myDivIcon = divIcon({
      className: 'my-marker',
      html: markerContents
    })

    return (
      <Marker
        position={this.props.position}
        icon={myDivIcon} />
    )
  }
}

然而,根据React docs

  

此[renderToString]只应在服务器上使用。

这是一个严格的规则,还是只是为了阻止人们绕过ReactDOM对DOM的有效管理?

我想不出另一种(更好的)方式来完成我所追求的目标。任何评论或想法将不胜感激。

3 个答案:

答案 0 :(得分:11)

根据新文件:https://reactjs.org/docs/react-dom-server.html

  

可以在服务器和浏览器中使用以下方法   环境:

     
      
  • renderToString()
  •   
  • renderToStaticMarkup()
  •   

答案 1 :(得分:5)

我知道这是一个太老的问题,但由于没有得到回答,我想分享我的想法。

我使用了同样的东西react-dom,但是由于文档建议不要在客户端使用它,我通过使用render的{​​{1}以另一种方式实现了它将自定义组件渲染为div

的方法
var myDiv = document.createElement('div');

ReactDOM.render(
  <MarkerContents data={this.props.data} />,
  myDiv
);

var myIcon = L.divIcon({ 
    iconSize: new L.Point(50, 50), 
    html: myDiv.innerHTML
});

答案 2 :(得分:1)

正如Thomas所说,是的,您可以在客户端上使用renderToString。不过,为了清楚起见,您将需要在客户端上导入ReactDOMServer,这似乎违反直觉,但似乎是正确的。示例(在客户端上):

import React from 'react';
import ReactDOMServer from 'react-dom/server';

const MyComp = (props) => {
  const html = ReactDOMServer.renderToString(<div>{someFunc(props)}</div>);
  // do something with your html, then
  return <div dangerouslySetInnerHTML={{__html: html}}></div>;
};