I'm working on an app using Leaflet (via react-leaflet). Leaflet directly manipulates the DOM. The react-leaflet library doesn't change that, it just gives you React components that you can use to control your Leaflet map in a React-friendly way.
In this app, I want to use custom map markers that are divs containing a few simple elements. The way to do that in Leaflet is to set your marker's icon
property to a DivIcon, in which you can set your custom HTML. You set that inner HTML by setting the DivIcon's html
property to a string containing the HTML. In my case, I want that HTML to be rendered from a React component.
In order to do that, it seems like the correct approach is to use ReactDOMServer.renderToString()
to render the Component that I want inside the map marker into a string, which I would then set as the html
property of the 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} />
)
}
}
However, according to the React docs:
This [renderToString] should only be used on the server.
Is this a strict rule, or is it only meant to dissuade people from circumventing ReactDOM's efficient management of the DOM?
I can't think of another (better) way to accomplish what I'm after. Any comments or ideas would be greatly appreciated.
According to the new documentation: https://reactjs.org/docs/react-dom-server.html
The following methods can be used in both the server and browser environments:
- renderToString()
- renderToStaticMarkup()