可以在.setHTML或.setDOMContent中的mapboxgl.Popup()中渲染react组件吗?

jas*_*ney 1 javascript mapbox reactjs mapbox-gl react-redux

我想知道是否有可能在mapboxgl.Popup()中渲染一个react组件。像这样:

    componentDidMount() {
            new mapboxgl.Popup()
            .setLngLat(coordinates)
            .setHTML(`<div>${<MapPopup />}<p>${moreText}</p></div>`)
            //.setDOMContent(`${<MapPopup />}`) ?????
            .addTo(this.props.mapboxMap)
    })
Run Code Online (Sandbox Code Playgroud)

还是应该使用ReactDOM.render完成?

ReactDOM.render(<MapPopup />, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)

该项目在弹出窗口中将具有连接到Redux存储的按钮和输入。

感谢您的输入!

thu*_*und 6

这有效:

addPopup(el: JSX.Element, lat: number, lng: number) {
    const placeholder = document.createElement('div');
    ReactDOM.render(el, placeholder);

    const marker = new MapboxGl.Popup()
                        .setDOMContent(placeholder)
                        .setLngLat({lng: lng, lat: lat})
                        .addTo(map);
}
Run Code Online (Sandbox Code Playgroud)

(在我使用打字稿来说明类型的地方,但是您可以将它们留给纯js使用。)将其用作

addPopup(<h1>Losers of 1966 World Cup</h1>, 52.5, 13.4);
Run Code Online (Sandbox Code Playgroud)

  • 为什么要将此标记为正确答案?这样做你会失去所有的提供者。这不是 React 的方式。 (2认同)

小智 6

你可以尝试实现React组件:

\n\n
export const Popup = ({ children, latitude, longitude, ...mapboxPopupProps }) => {\n    // this is a mapbox map instance, you can pass it via props\n    const { map } = useContext(MapboxContext);\n    const popupRef = useRef();\n\n    useEffect(() => {\n        const popup = new MapboxPopup(mapboxPopupProps)\n            .setLngLat([longitude, latitude])\n            .setDOMContent(popupRef.current)\n            .addTo(map);\n\n        return popup.remove;\n    }, [children, mapboxPopupProps, longitude, latitude]);\n\n    return (\n        /**\n         * This component has to have 2 divs.\n         * Because if you remove outter div, React has some difficulties\n         * with unmounting this component.\n         * Also `display: none` is solving that map does not jump when hovering\n         * \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf\n         */\n        <div style={{ display: \'none\' }}>\n            <div ref={popupRef}>\n                {children}\n            </div>\n        </div>\n    );\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

经过一些测试,我意识到Popup组件没有在地图上正确渲染。并且卸载该组件也不成功。这就是为什么有两个 div 作为回报。然而,它可能只发生在我的环境中。

\n\n

请参阅https://docs.mapbox.com/mapbox-gl-js/api/#popup了解更多信息mapboxPopupProps

\n\n

useEffect依赖项确保每次列表中的某些内容发生更改时都会重新创建 MapboxPopup 并清理以前的弹出实例return popup.remove;

\n


小智 2

我也一直在与这个作斗争。我发现的一种解决方案是使用 ReactDOM.render()。我创建了一个空的弹出窗口,然后使用 mapboxgl 生成的容器来渲染我的 React 组件。

    marker.setPopup(new mapboxgl.Popup({ offset: 18 }).setHTML(''));


     markerEl.addEventListener('mouseenter', () => {
        markerEl.classList.add('enlarge');

        if (!marker.getPopup().isOpen()) {
          marker.getPopup().addTo(this.getMap());

          ReactDOM.render(
            component,
            document.querySelector('.mapboxgl-popup-content')
          );
        }
      });
Run Code Online (Sandbox Code Playgroud)