遇到的问题
我们知道,在百度/高德地图中,有时需要加一些自定义html标签,但通常是用字符串传入(意味着只能用原生的写法),写起来非常不方便,如下图所示:
// 百度api
const infoWindow = new BMapGL.InfoWindow('');
infoWindow.setContent(
`<div style="color:#fff;background:#000;">${10+3}</div>`
)
map.openInfoWindow(infoWindow, map.getCenter()); // map是百度地图实例,请自行new一个
// 高德api
const infoWindow = new AMap.Marker({
position: new AMap.LngLat(114, 22),
content: `<div style="color:#fff;background:#000;">${10+3}</div>`,
});
map.add(infoWindow); // map是高德地图实例,请自行new一个
解决的方法
在react-dom/server中其实有一个函数(renderToString),可以帮我们把ReactDom节点转为字符串,我们只需将其引入,然后把用ReactDom节点包起来即可。
接下来,我们将之前的代码进行改写,如下所示:
import styled from 'styled-components';
import { renderToString } from 'react-dom/server'; // 引入renderToString
// stylus样式代码,你也可以用less或scss
const InfoWindowDiv = styled.div`
color: #fff;
background: #000;
`;
// 百度api
const infoWindow = new BMapGL.InfoWindow('');
infoWindow.setContent(
renderToString(<InfoWindowDiv>{10+3}</InfoWindowDiv>)
)
map.openInfoWindow(infoWindow, map.getCenter()); // map是百度地图实例,请自行new一个
// 高德api
const infoWindow = new AMap.Marker({
position: new AMap.LngLat(114, 22), // 经纬度请自行更改
content: renderToString(<InfoWindowDiv>{10+3}</InfoWindowDiv>),
});
map.add(infoWindow); // map是高德地图实例,请自行new一个
注意:renderToString 的作用仅仅是将 ReactDom 节点转为字符串,它并不具备交互功能(即 绑定在ReactDom上的事件 是无法生效的)。
如果你还希望实现交互功能 ,那么可以用react-dom/client中的函数,createRoot(参考文档) 或 hydrateRoot(参考文档)。
二者的语法都差不多,但应用场景不同,hydrateRoot一般用在服务端渲染(SSR)或者静态站点生成(SSG)的应用程序。
以高德api的代码进行改写,大致如下所示:
import { createRoot } from 'react-dom/client';
// 使用createRoot
function createContent(reactdom) {
const dom = document.createElement('div');
const content = createRoot(dom);
content.render(reactdom);
return dom;
}
// 高德api
const infoWindow = new AMap.Marker({
position: new AMap.LngLat(114, 22), // 经纬度请自行更改
content: createContent(<div onClick={() => alert('hello')}>{10+3}<div/>),
});
map.add(infoWindow); // map是高德地图实例,请自行new一个
import { hydrateRoot } from 'react-dom/client';
// 使用hydrateRoot
function createContent(reactdom) {
const dom = document.createElement('div');
hydrateRoot(dom, reactdom);
return dom;
}
// 高德api
const infoWindow = new AMap.Marker({
position: new AMap.LngLat(114, 22), // 经纬度请自行更改
content: createContent(<div onClick={() => alert('hello')}>{10+3}<div/>),
});
map.add(infoWindow); // map是高德地图实例,请自行new一个