我正在反应中创建一个简单的记忆游戏,并且遇到一个问题,可以一次选择两张以上的牌。仅单击两张卡时游戏可以正常运行,但如果选择更多卡则会中断。
我曾尝试将 openCards 中的卡片数量限制为 2 张,然后再翻转另一张,但没有成功。我还考虑过在您选择两张卡片时添加所有未向disabledCards开放的卡片,但这会将它们与已经匹配的卡片混合在一起。
function App() {
const [images, setImages] = useState([]);
const [openCards, setOpenCards] = useState([]);
const [shouldFlipBack, setShouldFlipBack] = useState(false);
const [disabledCards, setDisabledCards] = useState([]); //cards that are matched
const imageArray = [
{type: "penguin", image: penguin},
{type: "penguin", image: penguin},
{type: "snail", image: snail},
{type: "snail", image: snail},
{type: "chicken", image: chicken},
{type: "chicken", image: chicken},
{type: "raccoon", image: raccoon},
{type: "raccoon", image: raccoon},
{type: "fox", image: fox},
{type: "fox", image: fox}
];
useEffect(() => {
setImages((prevImages) => shuffleImages(prevImages));
}, []);
useEffect(() => {
if (openCards.length === 2) {
checkIfMatch();
setOpenCards([]);
}
}, [openCards]);
function checkIfMatch() {
if (openCards[0] === openCards[1]) {
console.log("match");
setDisabledCards(()=> [...disabledCards, openCards[0]]);
setShouldFlipBack(false);
} else {
console.log("not match");
setTimeout(() => {
setShouldFlipBack(true);
}, 1000);
}
setShouldFlipBack(false);
}
function Card({card, setOpenCards, openCards, shouldFlipBack, disabledCards}) {
const [isFlipped, setFlipped] = useState(false);
useEffect(() => {
if (!disabledCards.includes(card.type)) {
setTimeout(() => {
setFlipped(false);
}, 500);
}
}, [shouldFlipBack]);
function flipCard() {
if (!disabledCards.includes(card.type)) {
setFlipped(!isFlipped);
setOpenCards(()=> [...openCards, card.type]);
}
}
return (
<div className="card" onClick={flipCard}>
<div className={isFlipped ? "card-inner flipped" : "card-inner"}>
<div className="card-front"></div>
<div className="card-back">
{isFlipped && <img src={card.image} alt="card" />}
</div>
</div>
</div>
);
}
export default Card;
您可以执行以下两项操作之一:
我认为第一个提供了更好的设计,所以这就是我将展示的:
const noop = () => {}
function App() {
const [images, setImages] = useState([]);
const [shouldFlipBack, setShouldFlipBack] = useState(false);
const [isPending, setIsPEnding] = useState(false);
const imageArray = [
{type: "penguin", image: penguin, isFlipped: false, isMatcced: false},
{type: "penguin", image: penguin, isFlipped: false, isMatched: false},
{type: "snail", image: snail, isFlipped: false, isMatched: false},
{type: "snail", image: snail, isFlipped: false, isMatched: false},
{type: "chicken", image: chicken, isFlipped: false, isMatched: false},
{type: "chicken", image: chicken, isFlipped: false, isMatched: false},
{type: "raccoon", image: raccoon}, isFlipped: false, isMatched: false,
{type: "raccoon", image: raccoon, isFlipped: false, isMatched: false},
{type: "fox", image: fox, isFlipped: false, isMatcched: false},
{type: "fox", image: fox, isFlipped: false, isMatcched: false}
];
const flippedButNotMatched = useMemo(images => image.isFlippedlipped && !image.isMatched, [images]);
useEffect(() => {
setImages(shuffleImages(imageArray));
}, []);
const flipCard = useCallback(cardIndex => {
const card = images[cardIndex]
setImages(prevImages => image === card ? {...card, isFlipped: true} : image)
if (flippedButNotMatched.length == 1 && flippedButNotMatched[0].type === card.type) {
return;
}
setIsPending(true);
const cancel = setTimeout(() => {
setIsPending(true)
setImages(prevImages => image.isMatched ? image : {...image, isFlipped: false})
}, 500)
return () => clearTimeout(cancel)
}, [flippedButNotMatched]}
return (<div>
{images.map(image =>
<Card isFlipped={image.isFlipped} onClick={pending||image.isMapped ? noop: flipCard? />
)}
</div>)
}
祝你好运!