I am receiving an error when trying to return ( <div id="info_side">{info}</div> )
below. I have a _onClick
function that works and I can console log info
if I do not include {info}
anywhere in the return. How can I fix this? A more ideal approach would be to have another function that returns the {info}
data return
of the App hook such as _displayInfo
and {_displayInfo}
but I get the same error in that situation. Thanks for the help.
Here is the error: Error: Objects are not valid as a React child (found: object with keys {type, _vectorTileFeature, properties, layer, source, state}). If you meant to render a collection of children, use an array instead.
import React, { useState, useEffect } from 'react';
import 'mapbox-gl/dist/mapbox-gl.css';
import './styles/main.css';
import Nav from './components/nav';
import Search from './components/search';
import ReactMapGL, {Source, Layer, NavigationControl} from 'react-map-gl';
import geodata from './components/geodata';
const TOKEN = '...';
const mapStyle = '...';
const navStyle = {
...
};
const icon = {
id: 'icon',
...
};
const App = () => {
const [viewport, setViewport] = useState({longitude: -98.58, latitude: 39.83, zoom: 3.5})
const [locations, setLocations] = useState([])
const [geojson, setGeojson] = useState(null)
const [size, setSize] = useState({value: "All"})
const [info, setInfo] = useState([])
useEffect(() => {
setLocations(geodata)
_updateLocationData(size.value)
}, [locations]);
useEffect(() => {
setInfo(info);
}, [info]);
const _updateViewport = viewport => {
setViewport(viewport)
}
const _updateData = event => {
setSize({value: event.target.value})
_updateLocationData(event.target.value)
}
const _updateLocationData = (sizeValue) => {
var tempLocations = [];
locations.forEach(function(res) {
if (sizeValue === "All") {
tempLocations.push(res);
} else if (res.Size === sizeValue) {
tempLocations.push(res);
}
});
var data = {
type: "FeatureCollection",
features: tempLocations.map(item => {
return {
id: ...,
type: "Feature",
properties: {
Company: item.Company,
Address: item.Address,
Phone: item.Phone,
Long: item.Long,
Lat: item.Lat,
Size: item.Size,
},
geometry: {
type: "Point",
coordinates: [item.Long, item.Lat]
}
};
})
};
setGeojson(data);
}
const _onClick = event => {
const { features } = event;
const info = features && features.find(f => f.layer.id === 'icon');
setInfo(info); // Error: Objects are not valid as a React child (found: object with keys {type, _vectorTileFeature, properties, layer, source, state}). If you meant to render a collection of children, use an array instead.
console.log(info) // I can see the object with no error here if I do not add {info} in return ( <div id="info_side">{info}</div> )
}
return (
<div className="App">
<div className="inner-left map-container">
<ReactMapGL
{...viewport}
onViewportChange={_updateViewport}
width="100%"
height="100%"
mapStyle={mapStyle}
mapboxApiAccessToken={TOKEN}
onClick={_onClick}>
<Source id="my-data" type="geojson" data={geojson}>
<Layer {...icon} />
</Source>
<div style={navStyle}>
<NavigationControl onViewportChange={_updateViewport} />
<select onChange={_updateData} defaultValue={size.value}>
<option value="All">All</option>
<option value="Large">Large</option>
<option value="Medium">Medium</option>
<option value="Small">Small</option>
<option value="Very Small">Very Small</option>
</select>
</div>
</ReactMapGL>
</div>
<div className="inner-right info-container">
<Nav />
<Search />
<div id="info_side"> // where is error is thrown if I have {info} below
<div className="company">{info.properties.Company}</div>
<div className="address">{info.properties.Address}</div>
<div className="phone">{info.properties.Phone}</div>
</div>
</div>
</div>
);
}
export default App;