Надо запустить проверку на выигрыш при клике на элемент

Рейтинг: 0Ответов: 1Опубликовано: 04.03.2023

Есть небольшая игра на реакт. Найди пару карт. Если карточки совпали, то они становятся неактивными. Получается при клике на первую и вторую карточки они становится активными, но не отмечается как пара. И только после еще одного нажатия по полю игры они становятся неактивными и отмечаются парой. На каждую карточку добавлено событие по клику toggleClassCard. Как бы можно это исправить?

let cardsInfo = [
  { id: 1, number: 1, openStatus: false, successStatus: false },
  { id: 2, number: 1, openStatus: false, successStatus: false },
  { id: 3, number: 2, openStatus: false, successStatus: false }
]
const [cards, setCards] = useState(cardsInfo);
const [firstCard, setFirstCard] = useState(null);
const [secondCard, setSecondCard] = useState(null);
const setCardsInGame = (card) => {
    if (firstCard == null) {
      setFirstCard(card);
    } else {
      if (secondCard == null) {
        setSecondCard(card);
      }
    }
  };

 const gameLogicToWin = () => {
    if (firstCard !== null && secondCard !== null) {
      if (firstCard.number === secondCard.number) {
        setCards(
          cards.map((card) => {
            if (card.id === firstCard.id) {
              return {
                ...card,
                openStatus: false,
                successStatus: true,
              };
            }
            if (card.id === secondCard.id) {
              return {
                ...card,
                openStatus: false,
                successStatus: true,
              };
            }
            return card;
          })
        );
        setFirstCard(null);
        setSecondCard(null);
      }
    }
  }; 

const toggleClassCard = (id) => {
    setCards(
      cards.map((card) => {
        if (card.id === id) {
          setCardsInGame(card);
          if (card.successStatus === false) {
            return { ...card, openStatus: !card.openStatus };
          }
        }
        return card;
      })
    );
    gameLogicToWin();
  };

Ответы

▲ 0

Предложу такой вариант:

const cardsInfo = [
  { id: 1, number: 1, openStatus: false, successStatus: false },
  { id: 2, number: 1, openStatus: false, successStatus: false },
  { id: 3, number: 2, openStatus: false, successStatus: false }
];

export default function App() {
  const [cards, setCards] = useState(cardsInfo);
  const [open, setOpen] = useState(0);
  const [win, setWin] = useState(false);

  const clk = (id, num) => {
    if (open === num) {
      setWin(true);
      return;
    }
    if (open && open !== num) {
      setCards(
        cards.map((it) => {
          it.openStatus = false;
          return it;
        })
      );
      setOpen(0);
      return;
    }
    setCards(cards.map((it, idx) => {
      if (idx === id) it.openStatus = !it.openStatus
      return it;
    }));
    setOpen(num);
  };

  return (
    <>
      {!win ? (
        cards.map((item, id) => (
          <div
            className={item.openStatus ? "open" : ""}
            key={item.id}
            onClick={() => (!item.openStatus ? clk(id, item.number) : "")}
          >
            {item.number}
          </div>
        ))
      ) : (
        <>
          <div>Угадали!</div>
          <br />
          <button
            onClick={() => {
              setCards(
                cards.map((it) => {
                  it.openStatus = false;
                  return it;
                })
              );
              setWin(false);
              setOpen(0);
            }}
          >
            Повтор
          </button>
        </>
      )}
    </>
  );
}

При клике проверяет openState и индекс элемента.