如何使用 react-konva 和 react-google-maps/api 摆脱 'Text components are not supported for now in ReactKonva. You text is: "Loading..."'?

How to get rid of 'Text components are not supported for now in ReactKonva. You text is: "Loading..."' using react-konva and react-google-maps/api?

我想在 Google 地图层上渲染 Konva 形状。因为我使用的是 React,所以我使用 react-konva 和 react-google-maps/api 库来处理。

每次我 运行 yarn start,我都会得到这个错误:Text components are not supported for now in ReactKonva. You text is: "Loading..."

版本

项目目录结构

这是一个使用 create-react-app 构建的简单应用。

.
├── Makefile
├── README.md
├── Vagrantfile
├── bootstrap.sh
├── package.json
├── public
│   ├── classic-outline.png
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── components
│   │   ├── KonvaShape.js
│   │   └── Map.js
│   │  
│   ├── index.css
│   ├── index.js
│   ├── serviceWorker.js
│   └── setupTests.js
└── yarn.lock

这是我的组件:

App.js

import React from 'react';

import './App.css';

import KonvaShape from './components/KonvaShape';

function App() {
    return (
        <div>
            <KonvaShape />
        </div>
    );
}

export default App;

KonvaShape.js

import React from 'react';
import { Stage, Layer } from 'react-konva';

import Map from './Map';

function KonvaShape() {

    return (
        <Stage width={window.innerWidth / 2} height={window.innerHeight / 2}>
            <Layer>
                <Map />
            </Layer>
        </Stage>
    );
}

export default KonvaShape;

Map.js

import React from 'react';
import { GoogleMap, LoadScript } from '@react-google-maps/api';

const containerStyle = {
  width: '400px',
  height: '400px'
};

const center = {
  lat: -3.745,
  lng: -38.523
};

function Map() {
  const [map, setMap] = React.useState(null);

  const onLoad = React.useCallback(function callback(map) {
    const bounds = new window.google.maps.LatLngBounds();
    map.fitBounds(bounds);
    setMap(map)
  }, [])

  const onUnmount = React.useCallback(function callback(map) {
    setMap(null)
  }, [])

  return (
    <LoadScript
      googleMapsApiKey={"ENTER YOUR GOOGLE MAPS API KEY HERE"}
    >
      <GoogleMap
        mapContainerStyle={containerStyle}
        center={center}
        zoom={10}
        onLoad={onLoad}
        onUnmount={onUnmount}
      >
        { /* Child components, such as markers, info windows, etc. */}
        <></>
      </GoogleMap>
    </LoadScript>
  )
}

export default React.memo(Map)

我对 React 和 Konva 还很陌生,但我的猜测是我应该等待 Google 地图组件挂载,然后再渲染我的 KonvaShape 组件。我尝试使用 KonvaShape 自己的状态来管理这个技巧(正如这个答案所建议的 ReactJS: How to render components only after successful asynchronous call?)但我没有成功。

您正在尝试在此处注入 non-konva 元素:

<Stage width={window.innerWidth / 2} height={window.innerHeight / 2}>
  <Layer>
    <Map />
  </Layer>
</Stage>

无法直接执行此操作。 <Stage /> 仅支持 konva 节点。所以你可以在那里使用图层、组和形状。

如果你想添加 google 地图(这可能是一个 DOM 组件)你有两种方法:

  1. 将 google 地图以绝对位置放置在舞台顶部:
<Stage width={window.innerWidth / 2} height={window.innerHeight / 2}>
 {/* canvas internals */}
</Stage>
<div style={{ position: 'absolute', top: 0, left: 0 }}>
  <Map/>
</div>
  1. 或者您可以尝试使用 DOM portal 将地图注入 Konva 阶段。但这只是一个反应糖,在内部你仍然会在舞台顶部有绝对位置图。