繁体   English   中英

如何在 React 应用程序中实现谷歌地图搜索框

[英]How to implement Google Maps search box in a React application

我是 React 和谷歌地图的新手。 我正在使用google-map-react将 Google 地图集成到我的 React 应用程序中。 我能够成功加载 map 并添加标记。

但是在尝试添加 SearchBox 时出现错误。 我遵循了此处的文档SeachBox Documentation以及问题线程GitHub issue 但我仍然收到错误。 这段代码有什么问题?

在此处输入图像描述

这是我的代码

应用程序.js

import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './App.css';
import Driver from './Driver';
import Passenger from './Passenger';
import SearchBox from './SearchBox';


class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      apiReady: false,
      map: null,
      googlemaps: null
    };
  }

  static defaultProps = {
    center: {
      lat: 6.92,
      lng: 79.86
    },
    zoom: 15,
  };

  handleApiLoaded = (map, maps) => {
    // use map and maps objects
    if (map && maps) {
      this.setState({
        apiReady: true,
        map: map,
        googlemaps: maps
      });
    }
  };

  render({ apiReady, googlemaps, map } = this.state) {
    return (
      // Important! Always set the container height explicitly
      <div style={{ height: '100vh', width: '100%' }}>
        <GoogleMapReact
          bootstrapURLKeys={{ key: 'AIzaSyCk7pbkmNhknGumy2vgDykdgVj6lSreTt0', libraries: ['places'] }}
          defaultCenter={this.props.center}
          defaultZoom={this.props.zoom}
          yesIWantToUseGoogleMapApiInternals
          onGoogleApiLoaded={({ map, maps }) => this.handleApiLoaded(map, maps)}
        >
          <Driver
            lat={6.8972152}
            lng={79.8541014}
          />
          <Passenger
            lat={6.9272012}
            lng={79.8681316}
          />

          {apiReady && (<SearchBox
            //  placeholder={"123 anywhere st."}
            //  onPlacesChanged={this.handleSearch} 
            map={map}
            googlemaps={googlemaps} />)}
        </GoogleMapReact>
      </div>
      )
  }
}

export default App

搜索框.js

import React from 'react';
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

export default class SearchBox extends React.Component {

  static propTypes = {
    placeholder: PropTypes.string,
    onPlacesChanged: PropTypes.func
  }
  render() {
    return <input ref="input" placeholder={this.props.placeholder} type="text"/>;
  }
  onPlacesChanged = () => {
    if (this.props.onPlacesChanged) {
      this.props.onPlacesChanged(this.searchBox.getPlaces());
    }
  }
  componentDidMount() {
    var input = ReactDOM.findDOMNode(this.refs.input);
    // eslint-disable-next-line no-undef
    this.searchBox = new googlemaps.places.SearchBox(input);
    this.searchBox.addListener('places_changed', this.onPlacesChanged);
  }
  componentWillUnmount() {
    this.searchBox.removeListener('places_changed', this.onPlacesChanged);
  }

}

// eslint-disable-next-line no-unused-expressions
// eslint-disable-next-line no-lone-blocks
{/* <script defer type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyCk7pbkmNhknGumy2vgDykdgVj6lSreTt0&libraries=places"></script> */}

我已经粘贴了完整的代码,因为我不确定我哪里出错了。

google-map-react prop bootstrapURLKeys可以避免将脚本直接插入 HTML

<GoogleMapReact
    bootstrapURLKeys={{
        key: 'XXXXXXXXXXXXXXXXXXX',
        libraries: 'places'
    }}
......
/>

这里还有一个使用钩子的 Searchbox 的代码片段(不要忘记在父功能组件的情况下使用useCallback记住onPlacesChanged回调):

const SearchBox = ({ maps, onPlacesChanged, placeholder }) => {
    const input = useRef(null);
    const searchBox = useRef(null);

    const handleOnPlacesChanged = useCallback(() => {
        if (onPlacesChanged) {
            onPlacesChanged(searchBox.current.getPlaces());
        }
    }, [onPlacesChanged, searchBox]);

    useEffect(() => {
        if (!searchBox.current && maps) {
            searchBox.current = new maps.places.SearchBox(input.current);
            searchBox.current.addListener('places_changed', handleOnPlacesChanged);
        }

        return () => {
            if (maps) {
                searchBox.current = null;
                maps.event.clearInstanceListeners(searchBox);
            }
        };
    }, [maps, handleOnPlacesChanged]);

    return <input ref={input} placeholder={placeholder} type="text" />;
};

我在我的代码中发现了问题。 这是我犯的一个愚蠢的错误。 加载谷歌地图 api 不应该像我上面所做的那样在 SearchBox.js 中完成。 它应该加载到 inde.html 中,如下所示。 它解决了我的问题。

 <body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  <script type="text/javascript"
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDjrIzc3Vm83jIb8C-SQhU7JJ5Q-jCJGWg&libraries=places,geometry"></script>
</body>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM