I am trying to open a infowindow on a specific marker on click, however when i click one it appears that all of them are opening instead, and showing me this error:
React.Children.only expected to receive a single React element child.
This is what my code looks like right now:
import React, { Component } from 'react';
import { GoogleMap, Marker, withGoogleMap, withScriptjs, InfoWindow } from 'react-google-maps'
class Map extends Component {
state = {
isOpen: false
}
handleMarkerClick = () => {
this.setState({ isOpen: true})
}
render() {
return(
<div>
<GoogleMap
defaultZoom={13}
defaultCenter={{ lat: -22.9034778, lng: -43.1264636 }}
>{this.props.markers.map((marker, index) =>(
<Marker
key={index}
position={marker.location}
onClick={this.handleMarkerClick}
>{this.state.isOpen && <InfoWindow onCloseClick={this.handleMarkerClick}/>}
</Marker>
))}
</GoogleMap>
</div>
)
}
}
export default withScriptjs(withGoogleMap(Map))
Start of Edit
I made some changes to try and address the comment, however it isn't working yet, can you give me some hints on what i'm doing wrong, since i made some changes to the top component i will paste it here too:
import React, { Component } from 'react';
import Map from './Map.js'
import List from './List.js'
import escapeRegExp from 'escape-string-regexp'
import sortBy from 'sort-by'
class App extends Component {
state ={
locations:[
{
name: "Paróquia Nossa Senhora das Dores do Ingá",
location: {
lat: -22.9038875,
lng: -43.1252873
},
isOpen:false,
},
{
name: "Museu de Arte Contemporanea de Niteroi",
location: {
lat: -22.9078182,
lng: -43.1262919
},
isOpen:false,
},
{
name: "UFF - Faculdade de Direito",
location: {
lat: -22.9038469,
lng: -43.126024
},
isOpen:false,
},
{
name: "Ponte Rio-Niterói",
location: {
lat: -22.8701,
lng: -43.167
},
isOpen:false,
},
{
name: "Fundação Oscar Niemeyer",
location: {
lat: -22.888533927137285,
lng: -43.12815992250511
},
isOpen:false,
},
{
name: "Campo de São Bento",
location: {
lat: -22.905279,
lng: -43.107759
},
isOpen:false,
}
],
query:''
}
onToggleOpen = (location) => {
this.setState({ isOpen: !this.isOpen })
}
updateQuery = (query) => {
this.setState({ query: query.trim() })
console.log(query)
}
componentDidMount() {}
render() {
const { query, locations } = this.state
let filteredMarkers
if(query) {
const match = new RegExp(escapeRegExp(query), 'i')
filteredMarkers = locations.filter((location) => match.test(location.name))
}else {
filteredMarkers = locations
}
filteredMarkers.sort(sortBy('name'))
return (
<div className="App">
<div style={{height:`5vh`}}>
<input
type='text'
placeholder='Search locations'
value={query}
onChange={(event) => this.updateQuery(event.target.value)}
/>
</div>
<List
markers={filteredMarkers}
/>
<Map
onToggle={this.onToggleOpen}
googleMapURL="https://maps.googleapis.com/maps/api/js?&key=AIzaSyAiqO5W1p5FAFf8RZD11PGigUXSlmVHguQ&v=3"
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `80vh` }} />}
mapElement={<div style={{ height: `100%` }} />}
className="Map"
markers={filteredMarkers}
/>
</div>
);
}
}
export default App;
Map.js
import React, { Component } from 'react';
import { GoogleMap, Marker, withGoogleMap, withScriptjs, InfoWindow } from 'react-google-maps'
class Map extends Component {
render() {
return(
<div>
<GoogleMap
defaultZoom={13}
defaultCenter={{ lat: -22.9034778, lng: -43.1264636 }}
>{this.props.markers.map((marker, index) =>(
<Marker
key={index}
position={marker.location}
onClick={() => this.props.onToggle(marker)}
>{marker.isOpen && <InfoWindow onCloseClick={this.ontoggleOpen}>Hello</InfoWindow>}
</Marker>
))}
</GoogleMap>
</div>
)
}
}
export default withScriptjs(withGoogleMap(Map))
The problem i was having with React.Children.only expected to receive a single React element child.
was being caused because i didn't set a div inside the infowindow, so simply by adding it this particular problem was solved.
Here is what it used to look like:
<InfoWindow onCloseClick={this.handleMarkerClick}/>
here is what it should look like:
<InfoWindow onCloseClick={()=>this.props.onToggle(marker)}><div>Hello</div></InfoWindow>
or something along these lines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With