我有一个在reactJS中使用Google map api的应用程序:
https://github.com/strangebnb/react-airbnb
除了使用ReactJS组件作为Google Map API信息窗口的内容字符串之外,我已成功完成了我需要做的所有事情
我没有使用任何库或npm包来合并2.直接使用Google Maps API和ReactJS。
以下是我将渲染地图的整个组件的代码:
if ( variable != null )
在下面的方法中,我的contentString需要是反应组件,而不是 html或字符串,这是Google API想要的。
import React from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
import Navbar from '../navbar/Navbar.js'
import moment from 'moment'
import Rheostat from 'rheostat'
import _ from 'lodash'
import Slider from 'react-slick'
import PrevArrow from './PrevArrow'
import DateRangePickerGmapPage from '../date-range-picker/DateRangePickerGmapPage.jsx';
require('./searchResults.scss');
require('./_datepicker2.scss');
var sliderMin = 0;
export default class SearchResults extends React.Component {
constructor(props) {
super(props)
this.state = {
zoom: 12,
iCenter: {
lng: -90.1056957,
lat: 29.9717272
},
checker: false,
icon: {
path: 'M 0,0 20,0 20,16 14,16 10,24 6,16 0,16 z',
fillColor: '#FF5A5F',
fillOpacity: 1,
scale: 1.5,
strokeColor: 'RGBA(100,100,100,0.5)',
strokeWeight: 1,
},
entireHome: false,
privateRoom: false,
sharedRoom: false,
location: null,
data: null,
startDate: null,
endDate: null,
numGuests: 1,
values: [0,100],
sliderMin: 0,
sliderMax: 100,
roomTypeSelected: null,
picture_urls: [],
propertyNames: [],
star_rating: [],
price_array: []
}
axios.get('/getData').then(response => {
const x = response.data;
this.setState({
iCenter: {
lat: x.center_lat,
lng: x.center_lng
},
location: x.canonical_location_en
})
this.setState({
data: x,
location: x.location,
startDate: x.startDate,
endDate: x.endDate,
numGuests: x.numGuests,
sliderMax: x.max_price_total,
sliderMin: x.min_price_total,
values: [x.min_price_total, x.max_price_total]
}, ()=>{
this.renderMap(x);
});
})
}
static propTypes() {
initialCenter: React.PropTypes.objectOf(React.PropTypes.number).isRequired
}
render = () => {
var settings = {
// prevArrow: {PrevArrow},
arrows: true,
infinite: true,
slidesToShow: 1,
slidesToScroll: 1,
speed: 0.0001
};
let arrOfSliders = [];
if(this.state.picture_urls.length != 0){
for(let i = 0; i < this.state.picture_urls.length; i++){
var slider = <div><Slider className='slider' {...settings}>
<div className='img-container'><img className='slider-img' src={this.state.picture_urls[i][0]} ></img></div>
<div className='img-container'><img className='slider-img' src={this.state.picture_urls[i][1]} ></img></div>
<div className='img-container'><img className='slider-img' src={this.state.picture_urls[i][2]} ></img></div>
<div className='img-container'><img className='slider-img' src={this.state.picture_urls[i][3]} ></img></div>
<div className='img-container'><img className='slider-img' src={this.state.picture_urls[i][4]} ></img></div>
</Slider>
<p className='img-title'>{this.state.propertyNames[i]}</p>
<p>{this.state.star_rating[i]}</p>
</div>
arrOfSliders.push(slider);
}
}
return(
<div>
<Navbar/>
<div className = 'UpdatedText'>
<p>Current Zoom: {this.state.zoom} </p>
</div>
<main className = 'container-search'>
<div className = 'cards-container'>
<div className = 'date-panel'>
<span>Dates</span>
<DateRangePickerGmapPage location = {this.state.location} renderMap = {this.renderMap.bind(this)} className = 'date-picker'/> </div>
<div className = 'room-panel'>
<span> Room Types </span>
<div className = 'checkboxes'>
<label>Entire Home</label><input className='checkbox' id='entireHome' type='checkbox' name='Entire home/apt' value={this.state.entireHome} onChange={this.handleRoomTypes}/>
<label>Private Room</label><input className='checkbox' id='privateRoom' type='checkbox' name='Private room' value={this.state.privateRoom} onChange={this.handleRoomTypes}/>
<label>Shared Room</label><input className='checkbox' id='sharedRoom' type='checkbox' name='Shared room' value={this.state.sharedRoom} onChange={this.handleRoomTypes}/>
</div>
</div>
<div>
<Rheostat min={this.state.sliderMin} max={this.state.sliderMax} onValuesUpdated={this.updateValue} values={this.state.values} className = 'rheostat' />
<ol className='tempVals'>
<lh>Values</lh>
{this.state.values.map((value, i) => (
<li className='val' key={i}>
{this.props.formatValue ? this.props.formatValue(value) : value}
</li>
))}
</ol>
</div>
<div className='arrayOfSliders'>
{arrOfSliders.map((slider, i)=>{
return(
<div className='slider-container' key={i}>{slider}</div>
)
})}
</div>
</div>
<div className = 'GMap-canvas' ref = "mapCanvas" > </div>
</main>
</div>
)
}
updateValue = (sliderState) => {
this.setState({
values: sliderState.values,
}, this.renderMap(this.state.roomTypeSelected, this.state.values));
}
handleRoomTypes = (e) => {
if (e.target.value === 'false') {
this.setState({[e.target.id]: true}, ()=>{
let arr = [this.state.entireHome, this.state.privateRoom, this.state.sharedRoom];
return this.renderMap(this.convertToNames(arr));
});
} else if (e.target.value === 'true') {
this.setState({[e.target.id]: false}, ()=>{
let arr = [this.state.entireHome, this.state.privateRoom, this.state.sharedRoom];
return this.renderMap(this.convertToNames(arr));
}
);
}
}
convertToNames = (arr) => {
var names = ['Entire home/apt', 'Private room', 'Shared room'];
for(let i = 0; i < arr.length; i++){
if(arr[i] === false){
names.splice(i,1);
arr.splice(i,1);
i--;
}
}
console.log('names: ', names);
this.setState({roomTypeSelected: names});
return names
}
componentDidUnMount() {
google.maps.event.clearListeners(map, 'zoom_changed')
}
createMap = () => {
let mapOptions = {
zoom: this.state.zoom,
center: this.mapCenter()
}
return new google.maps.Map(this.refs.mapCanvas, mapOptions)
}
mapCenter = () => {
return new google.maps.LatLng(
this.state.iCenter.lat,
this.state.iCenter.lng
)
}
createMarker = (lat, lng, price) => {
var marker = new google.maps.LatLng(
lat, lng
);
return new Marker({
position: marker,
map: this.map,
icon: {
path: SQUARE_PIN,
fillOpacity: 0,
strokeColor: '#9BA198',
strokeWeight: 0,
},
map_icon_label: '<span class=price>$' + price + '</span>'
})
}
createInfoWindow = () => {
let contentString = `<div>hi</div>`
return new google.maps.InfoWindow({
map: this.map,
anchor: this.marker,
content: contentString
})
}
handleZoomChange = () => {
this.setState({
zoom: this.map.getZoom()
})
}
renderMap = (arr, priceRange = [null,null]) => {
console.log(arr);
axios.post('/search',{
searchVal: this.state.location,
startDate: this.state.startDate,
endDate: this.state.endDate,
numGuests: this.state.numGuests,
room_types: arr,
price_min: this.state.sliderMin,
price_max: this.state.sliderMax,
}).then(response => {
const x = response.data;
let listingsArray = response.data.results_json.search_results;
this.map = this.createMap()
this.latlngbounds = new google.maps.LatLngBounds();
let pics_array = [];
let propertyNames = [];
let star_rating = [];
let price_array = [];
for (let i = 0; i < listingsArray.length; i++) {
const lat = listingsArray[i].listing.lat
const lng = listingsArray[i].listing.lng
this.marker = this.createMarker(lat, lng, listingsArray[i].pricing_quote.rate.amount)
this.infoWindow = this.createInfoWindow()
var myLatLng = new google.maps.LatLng(lat, lng);
this.latlngbounds.extend(myLatLng);
pics_array.push(listingsArray[i].listing.picture_urls);
propertyNames.push(listingsArray[i].listing.name);
star_rating.push(listingsArray[i].listing.star_rating);
price_array.push(listingsArray[i].pricing_quote.rate.amount);
this.setState({picture_urls: pics_array,
propertyNames: propertyNames,
star_rating: star_rating,
price_array: price_array},
()=> { console.log('Testing ES6: ', this.state.propertyNames) }
)
}
console.log('max total price:', x.max_price_total)
if(x.max_price_total === null && x.min_price_total === null){
const min = Math.min(...price_array);
const max = Math.max(...price_array);
this.setState({
sliderMin: min,
sliderMax: max,
values: [min, max]
})
}
this.map.fitBounds(this.latlngbounds);
this.setState({
iCenter: {
lat: x.center_lat,
lng: x.center_lng
}
})
google.maps.event.addListener(this.map, 'zoom_changed', () => this.handleZoomChange())
})
}
}
Infowindows在renderMap方法中与地图和标记一起呈现。有没有解决这个问题,还是我运气不好?
答案 0 :(得分:2)
你可以尝试
ReactDOMServer.renderToString
https://facebook.github.io/react/docs/top-level-api.html
示例代码可能是
import ReactDOMServer from 'react-dom/server';
createInfoWindow = () => {
let contentString = ReactDOMServer.renderToString(<YourComponent/>);
return new google.maps.InfoWindow({
map: this.map,
anchor: this.marker,
content: contentString
})
}