I have a situation where once I click an image, I'd like it to get a border. And if i click it again, i'd like that border to be removed. BUT, i also want that border to be removed (or "moved") if another image is clicked instead!
i guess there are a couple of ways to go about this - both of which im not sure how to implement:
im using states that are passed down from like great-grandparents, so not sure i can post all the scripts - ill try to keep it in snippets instead.
my images: using 'next/image'
return(
<div key={attr} id={attrprops.attrChoice+':'+attr}>
<Image
src={imgSourceUrl}
alt={attrprops.alt}
width={attrprops.w}
height={attrprops.h}
onClick={()=>{ attrprops.setButtonClick(!attrprops.buttonClick);
attrprops.setBorder(attrprops.selectedAttr==attr ? false : true);
attrprops.setSelectedAttr(attr);
}}
/>
<br></br>
<div className='flex justify-center align-center'>{attr}</div>
</div>
);
my state change:
useEffect(()=>{
if (border&&buttonClick){
document.getElementById(`body_type:${selectedAttr}`).className = 'border-2 border-blue-500';
publishprops.setAttrNumber(4);
}
else if (!border&&buttonClick){
document.getElementById(`body_type:${selectedAttr}`).className = 'border:none';
publishprops.setAttrNumber(2);
}
},[border])
the way it is currently, it only adds the borders to selected images. really not sure what route to go on this...
In order to use React effectively, you need to change your thinking about the state a little. Your template should read easily, it should be clear what's the intent.
It looks like your example is pretty simple. It's either some image highlighted, or none.
Consider this simplified example:
import React, { useState } from 'react';
const images = [
'1.png',
'2.png',
'3.png',
'4.png',
'5.png',
];
const MyComponent = () => {
const [selectedImage, setSelectedImage] = useState(null);
return (
<ul>
{images.map(src => (
<img
key={src}
className={`
my-image
${selectedImage === src ? 'active' : ''}
`}
onClick={() => setSelectedImage(
selectedImage => (
selectedImage !== src
? src
: null
)
)}
/>
))}
</ul>
);
};
When selectedImage is null it means that no image has been clicked. And on click, we're either setting it to the clicked image, or setting it back to null if the same image has been clicked. And then you'd apply the border to images with active class. Simplified CSS:
.my-image {
border: 5px solid transparent;
}
.my-image.active {
border-color: red;
}