I’m using a React. I’m trying to change the style of the image that was clicked on. But the state is applied to all elements using this function.
The onClick event is applied to images. When clicking on one, the border of the others should change the border color to #a2a0ff. Only the image that was clicked on should have the color #4D4AFF.
import React from "react";
import './SearchPower.css';
import { YMaps, Map, Placemark} from '@pbe/react-yandex-maps';
function App() {
// Определение геопозиции пользователя
var getLocationPromise = new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(async function (position) {
resolve([position.coords.latitude, position.coords.longitude])
})
})
var [lat, setLat] = React.useState(0)
var [lng, setLng] = React.useState(0)
getLocationPromise.then((location) => {
setLat(location[0])
setLng(location[1])
})
if (lat == 0 && lng == 0) {
lat = 55.75
lng = 37.57 }
// Создание карты
var myMap = React.useMemo(
() => ({ center: [lat, lng], zoom: 9 })
);
// Работа с метками
const [imageHref, setImageHref] = React.useState("images/Marks/ZemMark.png");
const [ImgStyle, setImgStyle] = React.useState()
function changeGeoPosition(newLink) {
setImageHref(newLink);
setImgStyle("5px solid #4D4AFF")
}
return (
<div className="ContextSP">
<div className="DivMarks">
<img className="MarkLeftImage" src="images/Marks/ZemMark.png" onClick={function() {changeGeoPosition("images/Marks/ZemMark.png")}} style={{borderBottom: ImgStyle}}/>
<img className="MarkImage" src="images/Marks/Redcar1Mark.png" onClick={function() {changeGeoPosition("images/Marks/Redcar1Mark.png")}} style={{borderBottom: ImgStyle}}/>
<img className="MarkImage" src="images/Marks/Redcar2Mark.png" onClick={function() {changeGeoPosition("images/Marks/Redcar2Mark.png")}} style={{borderBottom: ImgStyle}}/>
<img className="MarkImage" src="images/Marks/GreencarMark.png" onClick={function() {changeGeoPosition("images/Marks/GreencarMark.png")}} style={{borderBottom: ImgStyle}}/>
<img className="MarkRightImage" src="images/Marks/YellowcarMark.png" onClick={function() {changeGeoPosition("images/Marks/YellowcarMark.png")}} style={{borderBottom: ImgStyle}}/>
</div>
<YMaps>
<Map style={{width: '100%', height: '100%', margin: '0 0 10px 0', border: '3px solid #4D4AFF'}} state={myMap}>
<div id="Prnt">
<Placemark geometry={[lat, lng]}
options={{
iconLayout: 'default#image',
iconImageHref: imageHref,
iconImageSize: [40, 40],
iconImageOffset: [0, 0],
iconOffset: [-5, -38]
}} id="myPosition"></Placemark>
</div>
</Map>
</YMaps>
</div>
)
}
export default App;
>Solution :
You only have a single ImgStyle variable, which is applied to the style of all the images, and whose value is set all of the onclicks, so of course they always have the same style.
To do it this way, you would need 5 separate state variables – one for each image. But I assume you actually only want the border on at most one image – the one just clicked on – and in that case you don’t need a separate state variable at all. Just compute the style based on the current imageHref and the image’s actual href:
function hasBorder(href) {
return href === imageHref;
}
And then apply it like this for each image (shown for one, but it should be obvious how this applies for the others):
<img className="MarkLeftImage" src="images/Marks/ZemMark.png" onClick={function() {changeGeoPosition("images/Marks/ZemMark.png")}} style={hasBorder("images/Marks/ZemMark.png") ? {borderBottom: "5px solid #4D4AFF" } : {}}/>
You could further simplify this by making an array of href strings and map-ing through that to generate each img tag.