I am making a game where I need different style for selected (pressed) item. I am trying to attach "selected" class to div if that div is clicked. In other words, I have a state:
const [pressedGifId, gifPressed] = useState(null);
and when
pressedGifId === gifId
then I should attach "selected" class to my div. Here is my simplified code:
import React, { useState, useEffect } from 'react';
export default function Game() {
const addedToGameGif = [];
const [pressedGifId, gifPressed] = useState(null);
const [photoCards] = useState([]);
useEffect(() => {
console.log(pressedGifId);
}, [pressedGifId]);
if (photoCards.length === 0) {
for (let i = 0; i < 5; i += 1) {
addedToGameGif.push([i, 'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg']);
}
}
addedToGameGif.map(item =>
photoCards.push(
<div key={item[0]}>
<div
onClick={() => gifPressed(`gif${item[0]}`)}
className={`${pressedGifId === `gif${item[0]}` && 'selected'}`}
>
<img src={item[1]} alt="bla" width="300" height="180" />
</div>
<br />
</div>,
),
);
return <div>{photoCards}</div>;
}
I can't see class updated accordingly to state: (it stays null)
But I get updated state in console ( I print it in useEffect):
My goal:
1) Change state (pressedGifId) on click
2) Add class "selected" to div if pressedGifId matches currently mapped item id ( gif${item[0]}
)
UPDATE2 :
Providen solution werent working for me since my photoCards were randomly picked photos and with provided solutions photos were changing into new randomly picked photos on every click (which I dont want to be). But it led me to the correct answer:
I put photoCards into a state (a hook) and set it on a first load (when photoCards array length is 0). It prevented from reloading and classes worked.
Here is updated code:
export default function Game(props) {
const [pressedGifId, setGifPressed] = useState(null);
const [gifCards, setGifCards] = useState([]);
useEffect(() => {
if (gifCards.length === 0)
setGifCards(randGen.getGifArray());
}
const renderCards = () =>
gifCards.map((item, index) => {
const gifId = `gif${item[0]}`;
return (
<div key={item[0]}>
<div
onClick={() => setGifPressed(gifId)}
onKeyPress={() => setGifPressed(gifId)}
role="button"
tabIndex="0"
className={`card ${getClass(gifId)}`}
>
<img
src={item[1]}
alt={txtCards[index][1]}
width="300"
height="180"
/>
</div>
</div>
);
});
return (
<div>
{renderCards()}
</div>
);
}
import React, { useState, useEffect } from 'react';
const Game = () => {
//here we are passing our gif data
const gifData = [
'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg',
'http://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg'
]
// pressedGifId : for gifId selection
const [pressedGifId, setGifPressed ] = useState(0);
// renderPhotoCards : this function return all cards
// onClick : setGifPressed to clicked gifId
// className : if our index of perticuler gif match with pressedGifId then we are setting it as selected
const renderPhotoCards = () =>
gifData.map(( item , index ) => (
<div key={index}>
<div
onClick={() => setGifPressed(index)}
className={ pressedGifId === index ? `gif${index} selected` : `gif${index}` }
>
<img src={item} alt="bla" width="300" height="180" />
</div>
<br />
</div>
)
)
return renderPhotoCards()
}
export default Game;
This is the line where I changed.
className={pressedGifId === `gif${item[0]}` ? "selected" : ""}
The entire code.
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function Game() {
const addedToGameGif = [];
const [pressedGifId, gifPressed] = useState(null);
let photoCards = [];
useEffect(() => {
console.log("->", pressedGifId);
}, [pressedGifId]);
if (photoCards.length === 0) {
for (let i = 0; i < 5; i += 1) {
addedToGameGif.push([
i,
"https://petapixel.com/assets/uploads/2019/06/manipulatedelephant-800x534.jpg"
]);
}
}
photoCards = addedToGameGif.map(item => (
<div key={item[0]}>
<div
onClick={() => gifPressed(`gif${item[0]}`)}
className={pressedGifId === `gif${item[0]}` ? "selected" : ""}
>
<img src={item[1]} alt="bla" width="300" height="180" />
{console.log(item)}
</div>
<br />
</div>
));
console.log("-", photoCards, addedToGameGif);
return <div>{photoCards}</div>;
}
This is working. I tried, check this JS snippet
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.