如何在ReactJS中动态设置Google Directions api的出行模式?

时间:2018-12-30 14:09:39

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

我正在尝试根据所选的单选按钮动态更新出行模式。

我已经阅读了api的说明文档,并尝试了以下方法。

class Transport extends React.Component {
  state={
    origin: '',
    destination: '',
    directions: '',
    mode: 'DRIVING'
  }

  setDirections(){
    const DirectionsService = new google.maps.DirectionsService();

      DirectionsService.route({
        origin: this.state.origin,
        destination: this.state.destination,
        travelMode: google.maps.TravelMode[this.state.mode]
      }, (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          this.setState({
            directions: result,
          });
        } else {
          console.error(`error fetching directions ${result}`);
          alert('Selected mode of transport is not available for the for the trip!');
        }
      });
  }

  showPlaceDetails(place) {
    let destination = sessionStorage.getItem('city');
    destination=destination.replace(/\+/g, ' ');
    console.log(destination);
    let origin = place.address_components[0].long_name.toString();
    try{
        origin+= ' ' + place.address_components[2].long_name.toString();
    }catch(e){}
    console.log(origin);

    this.setState(() => ({origin, destination}));

    this.setDirections();
}

onModeChange = (e) =>{
  const mode = e.target.value;
  console.log(mode);

  this.setState(() => ({mode}));

  this.setDirections();
}

   render() {
   const GoogleMapExample = withGoogleMap(props => (
      <GoogleMap
        defaultCenter = { { lat: 40.756795, lng: -73.954298 } }
        defaultZoom = { 13 }
      >
      {this.state.directions && <DirectionsRenderer directions={this.state.directions} />}
      </GoogleMap>
   ));
   return(
      <div>
        <div className='travel-details-container'>
          <div>
            <CitySuggestionBar onPlaceChanged={this.showPlaceDetails.bind(this)} />
            <div>
            <label htmlFor="driving">Driving</label>
            <input type="radio" name="transport-type" id="driving" value="DRIVING" 
            onChange={this.onModeChange} defaultChecked />
            <label htmlFor="transit">Bus/Train</label>
            <input type="radio" name="transport-type" id="transit" value="TRANSIT"
            onChange={this.onModeChange} />
            <label htmlFor="air">Airways</label>
            <input type="radio" name="transport-type" id="air" value="AIRWAYS"
            onChange={this.onModeChange} />
          </div>
          </div>
        </div>
        <GoogleMapExample
          containerElement={ <div style={{ height: `500px`, width: '100%' }} /> }
          mapElement={ <div style={{ height: `100%` }} /> }
        />
      </div>
   );
   }
};

我已在该状态下将默认模式设置为DRIVING,并且选中的默认单选也是DRIVING。但是,当我将其更改为“公共汽车/火车”时,它似乎仍在地图上行驶。但是,最令人困惑的是,当我切换回驾驶状态时,地图现在更新为“公交”并且状态为“驾驶”。

请帮助! 预先感谢。

2 个答案:

答案 0 :(得分:0)

这很可能是由于setStateState and Lifecycle documentation中所述是异步的。通过在this.setDirections()之后立即调用this.setStatethis.state.mode将具有旧的状态值,直到异步更新完成。为了解决这个问题,setState为状态更新完成后运行的回调函数采用了第二个参数(请参见here)。您可以像this.setState({ mode }, () => this.setDirections())这样使用。另外,您可以使用componendDidUpdate并检查是否更改了任何从属值,然后调用this.setDirections()

答案 1 :(得分:0)

您可以使用JavaScript动态更改出行方式。请检查以下代码:

在HTML中,提供如下选择框:

<select class="form-control" id="mode">
  <option value="">Select Mode</option>
  <option value="WALKING">Walking</option>
  <option value="DRIVING">Driving</option>
  <option value="BICYCLING">Bicycling</option>
  <option value="TRANSIT">Transit</option>
</select>

在JavaScript的initMap()函数中,添加如下内容:

  document.getElementById("mode").addEventListener("change", () => {
    calculateAndDisplayRoute(directionsService, directionsRenderer);
  });

在这里,calculateAndDisplayRoute是JavaScript中的一个单独函数:

function calculateAndDisplayRoute(directionsService, directionsRenderer)
{
  var selectedMode = document.getElementById("mode").value;
  directionsService.route(
    {
      origin: Your Origin Values,
      destination: Your Destination Values,
      travelMode: google.maps.TravelMode[selectedMode]
    },
    (response, status) => {
      if (status == "OK") {
        directionsRenderer.setDirections(response);
      }
      else {
        window.alert("Directions request failed due to " + status);
      }
    }
  );
}