Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The useState hook changes the state of all components, not just the desired one

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 :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading