Reputation: 72
I have a page in left side div items like item's image,title,its details, address ex. And on the right side I have a map (Leaflet Map) showing markers of address which taking from all of these left side items. Now I want to display marker location on map when mouse hover to the left information with its address. Shortly you can see live example in airbnb.com
I am using React Leaflet for map and React as you see. But data doesn't fetch from db yet, it is dummy data. Address is defined with lat and lng coords
Bikes.js
import { BIKES, BikeTypes, BikeSize } from '../../data'
const Bikes = () => {
return <div className="bikes-page">
<div>
<hr className="bike-bottom-line" />
<BikesList items={BIKES} />
</div>
<div className="bikes-map">
<MapContainer style={{ height: '50rem' }} coords={BIKES} mapZoom={9} />
</div>
</div>
}
export default Bikes
MapContainer.js (Component made with react-leaflet)
const MapContainer = (props) => {
const DEFAULT_LATITUDE = 40.500;
const DEFUALT_LANGITUDE = 49.500;
return (
<Map style={props.mapStyle} center={[DEFAULT_LATITUDE, DEFUALT_LANGITUDE]} zoom={props.mapZoom || 7} >
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{
props.coords ?
props.coords.map(mark => {
return <Marker
position={[mark.location.lat, mark.location.lng]}
icon={biker}
key={mark.id} >
<Popup className="popup">
<Link to={`/b/${mark.id}`} className="popup-container">
<img src={mark.images[0]} alt={mark.title} />
<div className="popup-container__title">
<h3> {mark.title} </h3>
{mark.size}" · {mark.price.first}azn/s
</div>
</Link>
</Popup>
</Marker>
}) : null
}
</Map >
)
}
export default MapContainer
BikesList.js (left side - List)
const BikesList = (props) => {
if (props.items.length === 0) {
return <h2>Elan tapılmadı</h2>
}
return (
<ul className="bikes-list">
{props.items.map((bike) => (
<BikeItem
key={bike.id}
id={bike.id}
image={bike.images[0]}
title={bike.title}
city={bike.city}
size={bike.size}
price={bike.price.first}
creator={bike.creator}
maxLength={24}
/>
))}
</ul>
)
}
export default BikesList
Upvotes: 0
Views: 1524
Reputation: 72
I found a solution myself. It was easy :) Here it is:
First , in the Bikes.js file, I made an isHovered state and gives it null as a default. Then made handleHoverMarker(id) function with id which will get it from specific hovered item's id. In function I changed setIsHovered's value to this sent id. So then I shared isHovered and handleHoverMarker with props.
Bikes.js
const [isHovered, setIsHovered] = useState(null)
const handleHoverMarker = (id) => {
setIsHovered(id)
}
<div>
<BikesList handleHoverMarker={handleHoverMarker} items={filteredDataState} />
</div>
<div className="bikes-map">
<MapContainer isHovered={isHovered} style={{ height: '50rem' }} coords={BIKES} mapZoom={9} />
</div>
Second, handleHoverMarker props sent to the BikeItem component which represents each of items in list.
BikesList.js
<ul className="bikes-list">
{props.items.map((bike) => (
<BikeItem
key={bike.id}
id={bike.id}
image={bike.images[0]}
title={bike.title}
city={bike.city}
size={bike.size}
price={bike.price.first}
creator={bike.creator}
maxLength={24}
handleHoverMarker={props.handleHoverMarker}
/>
))}
</ul>
In the BikeItem.js set mouseHover events and pass the id with handleHoverMarker(id) function. So we will know which item hovered with id.
Note: I didn't write all codes in BikeItem.js only took the necessary part
BikeItem.js
<li onMouseEnter={()=> props.handleHoverMarker(props.id):null} onMouseLeave={()=>props.handleHoverMarker(null):null} key={props.id}>
So here we come back to the MapContainer which will show hovered item's location
MapContainer.js
{props.coords ?
props.coords.map(mark => {
return <Marker
position={[mark.location.lat, mark.location.lng]}
icon={biker}
opacity={props.isHovered === mark.id ? .7 :1}
key={mark.id} >
<Popup className="popup">
<Link to={`/b/${mark.id}`} className="popup container">
<div className="popup-container__title">
<h3> {mark.title}</h3>
</div>
</Link>
</Popup>
</Marker>
}) : null}
Here I changed opacity value conditionally with props.isHovered which we sent from Bikes.js file.
Note: I couldn't changed marker's style because I didn't found a way from documentaton of leaflet map. So logic is the same, you can do it with Google Maps too. Enjoy good luck :)
Upvotes: 1