Reputation: 37
I am new to React and am trying to create a simple card game. When a card is clicked, it should be selected and assigned a classname of " selectedCard". So when it re-renders, the selected card will be lifted up. However, the selected card did not lift up onClick, my guess is that it did not re-render.
Here is my code snippet:
Player.js:
const Player = (props) =>{
const [selectedCards, setSelectCard] = useState([]);
const selectCard = (card) => {
let newSelectedCards = selectedCards
if(newSelectedCards.includes(card) ) {
newSelectedCards.splice(newSelectedCards.indexOf(card), 1)
} else {
newSelectedCards.push(card)
}
setSelectCard(newSelectedCards)
console.log('changed');
}
return(
<div className="player-container">
{props.cards && props.cards.map((card, i) => {
let selected = selectedCards.includes(card)
return(<Card key={i} card={card} user="player" selectCard={selectCard} selected={selected}/>)
}
)}
)
}
Card.js
const Card = (props) =>{
const path = props.card.imagePath
const [selected, setSelected] = useState(props.selected)
useEffect(() => { setSelected(props.selected) }, [props.selected]);
{/*My effort to make it work*/}
const classname = (selected) ? "selectedcard" : ""
return(
<img onClick={() => props.selectCard(props.card)} className={"card " + classname} alt = "card-image" src={images[path]}/>)
}
css
.selectedcard{
margin-bottom: 40px;
border-radius: 6px;
box-shadow: 0px 0px 5px #fff !important;
}
Upvotes: 3
Views: 1572
Reputation: 282120
You shouldn't mutate the state while updating it, if you do so React sees in reference check that thee reference is same and assumes nothing has changed and doesn't trigger a re-render.
Follow the concept of immutability while updating react state. You can update it using Array.prototype.slice
and spread syntax
for deleting the item and using Array.prototype.concat
for adding an item
const selectCard = (card) => {
let newSelectedCards =[];
if(newSelectedCards.includes(card) ) {
const index = selectedCards.indexOf(card)
newSelectedCards = [...selectedCards.slice(0, index), ...selectedCards.slice(index + 1)]
} else {
newSelectedCards = selectedCards.concat([card]);
}
setSelectCard(newSelectedCards)
console.log('changed');
}
Upvotes: 3