1

我正在學習反應,並試圖創建一個Google地方的自動完成組件,在導軌應用程序中使用rails rails gem上的反應。這是我迄今爲止所需要的,需要一些幫助完成它。Google Places Autocomplete React Component

我想我有一個問題,讓谷歌JavaScript庫加載正確。從下面的控制檯看到錯誤信息(注意我的應用程序中運行了正確的[KEY])。

Navigated to https://react-on-rails-basic-tutorial-mcl282.c9users.io/ 
js?key=[KEY]&libraries=places&callback=initAutocomplete:102 Uncaught Yc {message: "initAutocomplete is not a function", name: "InvalidValueError", stack: "Error↵ at new Yc (https://maps.googleapis.com/m…libraries=places&callback=initAutocomplete:139:73"} 
Yg @ js?key=[KEY]&libraries=places&callback=initAutocomplete:102 
(anonymous) @ js?key=[KEY]&libraries=places&callback=initAutocomplete:139 
google.maps.Load @ js?key=[KEY]&libraries=places&callback=initAutocomplete:21 
(anonymous) @ js?key=[KEY]&libraries=places&callback=initAutocomplete:138 
(anonymous) @ js?key=[KEY]&libraries=places&callback=initAutocomplete:139 
createReactElement.js?74ab:40 RENDERED GoogleAutoComplete to dom node with id: GoogleAutoComplete-react-component-f9a3e037-df00-4f35-9a7c-103c33b1208e with props, railsContext: Object {text: "google autocomplete"} Object {inMailer: false, i18nLocale: "en", i18nDefaultLocale: "en", href: "https://react-on-rails-basic-tutorial-mcl282.c9users.io/", location: "/"…} 
clientStartup.js?0ac5:149 Uncaught TypeError: ReactOnRails encountered an error while rendering component: GoogleAutoComplete.Original message: Cannot read property 'Autocomplete' of undefined 
    at GoogleAutoComplete.initAutocomplete (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:3586), <anonymous>:44:48) 
    at GoogleAutoComplete.componentDidMount (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:3586), <anonymous>:38:12) 
    at eval (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2842), <anonymous>:265:25) 
    at measureLifeCyclePerf (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2842), <anonymous>:75:12) 
    at eval (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2842), <anonymous>:264:11) 
    at CallbackQueue.notifyAll (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2296), <anonymous>:76:22) 
    at ReactReconcileTransaction.close (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:3004), <anonymous>:80:26) 
    at ReactReconcileTransaction.closeAll (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2398), <anonymous>:206:25) 
    at ReactReconcileTransaction.perform (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:2398), <anonymous>:153:16) 
    at batchedMountComponentIntoNode (eval at <anonymous> (webpack-bundle.self-cdcd22e….js?body=1:3130), <anonymous>:126:15) 

下面是相關代碼:

index.html.erb

<html> 
    <body> 
    <%= react_component("GoogleAutoComplete") %> 

    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAnhYQqHo2V5AcFpcKKPX6rz0bVrw7xmZg&libraries=places&callback=initAutocomplete" 
     ></script> 
    </body> 
</html> 

GoogleAutoComplete.jsx

import React, { PropTypes } from 'react'; 

export default class GoogleAutoComplete extends React.Component { 
    static propTypes = { 
    } 
    constructor(props) { 

     super(props); 
     this.state = { 
      autocomplete: {} 
     } 
    } 

    componentDidMount() { 
     this.initAutocomplete(); 
    } 

    initAutocomplete() { 
     // eslint-disable-next-line no-undef 
     const autocomplete = new google.maps.places.Autocomplete((this.refs.autoCompletePlaces), {types: ['geocode']}); 

     autocomplete.addListener('place_changed', this.fillInAddress); 
     this.setState({ autocomplete }); 
    } 

    geolocate() { 
     if (navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(function(position) { 
      const geolocation = { 
      lat: position.coords.latitude, 
      lng: position.coords.longitude 
      }; 
     }); 
     } 
    } 

    fillInAddress() { 
     const componentForm = { 
     street_number: 'short_name', 
     route: 'long_name', 
     locality: 'long_name', 
     administrative_area_level_1: 'short_name', 
     country: 'long_name', 
     postal_code: 'short_name' 
     }; 
    // Get the place details from the autocomplete object. 
     const place = autocomplete.getPlace(); 
     for (let component in componentForm) { 
     this.refs.component.value = ''; 
     this.refs.component.disabled = false; 
     } 

    // Get each component of the address from the place details 
    // and fill the corresponding field on the form. 
    for (let i = 0; i < place.address_components.length; i++) { 
     const addressType = place.address_components[i].types[0]; 
     if (componentForm[addressType]) { 
     const val = place.address_components[i][componentForm[addressType]]; 
     this.refs.addressType.value = val; 
     } 
    } 
    } 



    render() { 
    return (
     <div> 
     <div id="locationField"> 
      <input 
      id="autocomplete" 
      placeholder="Enter your address" 
      onFocus={this.geolocate} 
      onChange={this.handleInputChange} 
      ref="autoCompletePlaces" 
      /> 
     </div> 
     <table id="address"> 
      <tbody> 
      <tr> 
       <td>Street address</td> 
       <td> 
       <input 
        id="street_number" 
        disabled="true"/> 
       </td> 
       <td> 
       <input 
        id="route" 
        disabled="true"/> 
       </td> 
      </tr> 
      <tr> 
       <td>City</td> 
       <td> 
       <input 
        id="locality" 
        disabled="true"/> 
       </td> 
      </tr> 
      <tr> 
       <td>State</td> 
       <td> 
       <input 
        id="administrative_area_level_1" 
        disabled="true"/> 
       </td> 
       <td>Zip code</td> 
       <td> 
       <input 
        id="postal_code" 
        disabled="true"/> 
       </td> 
      </tr> 
      <tr> 
       <td>Country</td> 
       <td> 
       <input 
        id="country" 
        disabled="true"/> 
       </td> 
      </tr> 
      </tbody> 
     </table> 
     </div>  
    ); 
    } 
} 

回答

2

發生錯誤的原因是initComplete()不可用全球範圍。 initComplete()是一個React組件方法,您不能在組件外調用它。

要將callback參數傳遞給Google Maps API,您需要異步加載庫,而不像您那樣使用<script>標記。

請查看以下存儲庫以查看它們如何處理Google地圖庫的異步加載。

https://github.com/fullstackreact/google-maps-react

+0

我想我理解的概念在這裏,需要加載在它與谷歌地圖API的腳本高階組件,給我做了它所需要的功能組件。但是,我不太瞭解如何實現它。他們給這個代碼示例:「進口{} GoogleApiWrapper從 'GoogleMapsReactComponent' // ... 出口類容器來擴展React.Component {} 出口默認GoogleApiWrapper({ apiKey:__GAPI_KEY__ })(集裝箱) '我如何使用我的GoogleAutoComplete.jsx組件實現這個功能? –

+0

@MichaelLee'GoogleApiWrapper'組件將'loaded'屬性傳遞給包裝組件。只有在加載庫後,此道具纔會設置爲true。當一個prop改變時,被包裝的組件會再次呈現自己,你可以檢查'componentDidMount()'中的'loaded'是否爲true,如果它爲true,則調用'initAutocomplete()'。 –

+0

這個工程!有一件事讓我感到沮喪,那就是該博客有錯誤,請參閱以下鏈接:https://github.com/fullstackreact/google-maps-react/issues/18; –

相關問題