TypeError:无法读取未定义的属性“地图”

时间:2018-11-21 11:59:57

标签: reactjs google-maps create-react-app

  componentDidMount() {
    window.initMap = this.initMap
    ((doc, script) => {
        const element = doc.getElementsByTagName(script)[0];
        const fjs =element;
        let js = doc.createElement(script);
        js.src = `https://maps.googleapis.com/maps/api/js?key=${this.props.mapKey}&callback=initMap`
        if (fjs && fjs.parentNode) {
            fjs.parentNode.insertBefore(js, fjs)
          } else {
            doc.head.appendChild(js)
          }
    })(document, 'script')
}

initMap = () =>{

        let uluru = {lat: -25.344, lng: 131.036};
        let map = new window.google.maps.Map(
            document.getElementById('map'), {zoom: 4, center: uluru});


}

我正在动态创建脚本标签以加载google函数,并在运行此脚本时将全局initMap函数分配给本地函数,但我无法读取未定义的属性映射 有人可以帮助我做错什么事吗?

1 个答案:

答案 0 :(得分:0)

问题是代码在脚本加载之前运行。
已经有可以实施Google Maps的开源项目,但是如果您仍然想自己实施,则可以使用scriptjs。使用此软件包,您可以导入资源并在加载资源时运行功能。在这种情况下,不需要脚本标签。

运行示例:

class GoogleMap extends React.Component {
  componentDidMount() {
    if (!window.google || !window.google.maps) {
      const { googleKey } = this.props;
      // require is not working inside stackoverflow snippets
      // we are using a cdn for scriptjs, you can use npm
      //const $script = require(`scriptjs`);
      $script(
        `https://maps.googleapis.com/maps/api/js?key=${googleKey}`,
        this.handleGoogleLoad
      );
    }
  }

  componentDidUpdate(prevProps) {
    const { position } = this.props;
    if (prevProps.position !== position) {
      this.map && this.map.setCenter(position);
      this.marker && this.marker.setPosition(position);
    }
  }

  handleGoogleLoad = () => {
    const { position } = this.props;
    this.map = new window.google.maps.Map(this.mapRef, {
      scaleControl: true,
      center: null,
      zoom: 10
    });
    this.marker = new window.google.maps.Marker({
      map: this.map,
      position: position
    });

    this.map.setCenter(position);
    this.marker.setPosition(position);
  };

  render() {
    return <div style={{ height: "350px" }} ref={ref => (this.mapRef = ref)} />;
  }
}

class App extends React.Component {
  state = { lat: 40.741895, lng: -73.989308, googleKey: "" };

  onInputChange = ({ target }) => {
    this.setState({ [target.name]: target.value });
  };

  render() {
    const { lat, lng, googleKey } = this.state;
    const position = { lat: Number(lat), lng: Number(lng) };
    return (
      <div className="App">
        <div>
          <label>Paste google key </label>
          <input
            name="googleKey"
            value={googleKey}
            onChange={this.onInputChange}
          />
          <hr />
          <div>Change coords</div>
          <input name="lat" value={lat} onChange={this.onInputChange} />
          <input name="lng" value={lng} onChange={this.onInputChange} />
        </div>
        <hr />
        {googleKey ? (
          <GoogleMap position={position} googleKey={googleKey} />
        ) : (
          <div>Missing google key</div>
        )}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/script.js/2.5.9/script.min.js"></script>
<div id="root"/>