I am making a game with react, it's a memory game where you match images.so what I want to archive is, when I click on the div it selects the child of the div(the image) and then add class to the parent and then add class to the child itself. Based on the game logic I have to select the the child element first then if pass some conditions I then add a class to it and it's parent element. look at the code I currently have but it's not working, please help me out. `
let currentElement;
const imageclick=(e)=>{
//select current image
currentElement=e.target.firstElementChild;
// some game logic the add class to child and parent
//add class to parent
currentElement.closest("div").classList.add("show");
//add class to child
currentElement.classList.remove("hidden")
}
const app=()=>{
return(
<div className="imgDiv transition" key={i} onClick={imageclick}>
<img src={img} alt="" className="tileImage hidden" />
</div>
)
}
`
There are multiple approaches.
One way is to store your images in an array of objects. This array is used to render all of your images. You could even shuffle the array to make the order random.
Inside your component you have a state. This state tracks the index of the currently selected image of the array. The initial state can be null
to indicate that there is no current selected image.
While looping over your images, check for each image if the selectedImageIndex
is equal to the index of the current image. If so, pass some extra classes.
(You don't need to toggle hidden
class on the image. Use the show
class on the div to either show or hide the child image).
Pass the index
of the current image to the imageClick
function in the onClick
handler of the div
. Whenever we click an image, we want to set the index
of the image as our selectedImageIndex
.
The component will now rerender and add the class to the clicked div
.
I've modified the answer according to your comment. This example allows for 2 indexes to be stored into the state that tracks the selected images.
Whenever you click the same, the image is deselected. Whenever you click another image it will add its index
to the state.
In the useEffect
hook you can asses if the images corresponding to the indexes have a similar src
or other property that matches.
(I would recommend creating a more robust system in which YOU say which images are the same instead of depending on the URL to be the same. Eg two images can be the same while having different URL's)
const images = [
{
id: 'A',
src: 'your-image.jpg',
alt: 'Something about your image'
},
{
id: 'B'
src: 'your-other-image.jpg',
alt: 'Something about your image'
},
{
id: 'A' // The match to the other A
src: 'the-other-image-that-matches-the-first.jpg',
alt: 'Something about your image'
}
];
const App = () => {
const [selectedImageIndexes, setSelectedImageIndexes] = useState([null, null]);
const imageClick = index => {
setSelectedImageIndex(currentIndexes => {
// If the same index is clicked, deselect all.
if (currentIndexes.includes(index)) {
return [null, null];
}
// If no indexes have been set.
if (currentIndexes.every(index => index === null)) {
return [index, null];
}
// Set the second clicked image.
return [currentIndexes[0], index];
});
};
useEffect(() => {
// If both indexes are set.
if (selectedImageIndexes.every(index => index !== null) {
/**
* With the indexes in the selectedImageIndexes state,
* check if the images corresponding to the indexes are matches.
*/
if (selectedImageIndexes[0].id === selectedImageIndexes[1].id) {
// Match!
}
}
}, [selectedImageIndexes]);
return (
<div className="images">
{images.map((image, index) => {
const className = selectedImageIndex.includes(index) ? 'show' : '';
return (
<div className="imgDiv transition" key={`img-div-${index}`} onClick={() => imageClick(index)}>
<img src={image.src} className="tileImage" alt={image.alt} />
</div>
);
})}
</div>
)
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.