Próbuję zbudować tę grę pamięciową, na razie mój kod renderuje serię nazw pokemonów za pomocą przycisku i za każdym razem, gdy klikniesz przycisk, nazwa pokemona jest przechowywana w tablicy. Ale teraz, ...

0
Chen 22 czerwiec 2021, 21:56

4 odpowiedzi

Najlepsza odpowiedź

Należy dodać sprawdzanie podczas ustawiania klikniętych elementów za pomocą funkcji include() i można poprawić rejestrowanie w celu sprawdzenia, czy elementy zostały wielokrotnie kliknięte. Zmieniłem funkcję logowania i funkcję pushPokemon. Demo pracy w następujący sposób:

import React, { useState, useEffect } from "react";

function Cards() {
  const [items, setItems] = useState([]);
  const [clicked, setClicked] = useState([]);

  useEffect(() => {
    fetch("https://pokeapi.co/api/v2/pokemon/?limit=12")
      .then((res) => res.json())
      .then(({ results }) => {
        setItems(results);
      });
  }, []);

  useEffect(() => {
    console.log(clicked);
  });

  const pushPokemon = (e) => {
    var pokemon = e.target.innerHTML;
    if(!clicked.includes(pokemon)) {
        setClicked([...clicked, pokemon]);
    } else {
        console.log('Repeated item clicked!')
    }
  };

  return (
    <div>
      {items.map((item) => (
        <button onClick={pushPokemon}>{item.name}</button>
      ))}
    </div>
  );
}

export default Cards;
2
Tejas Morajkar 22 czerwiec 2021, 19:42

Sugerowałbym nie używać innerHTML, a zamiast tego po prostu przekazywać nazwę pokemona, którego próbujesz dodać do pushPokemon. Również w twoim przykładzie dodałbyś pokemona po raz drugi, zanim twój useEffect na clicked uruchomi się w celu wykrycia duplikatu. Z tego powodu myślę, że chcesz sprawdzić duplikaty w samej funkcji pushPokemon.

import React, {useState, useEffect} from 'react'
    
function Cards() {
  const [items, setItems] = useState([])
  const [clicked, setClicked] = useState([])

  useEffect(() => {
    fetch("https://pokeapi.co/api/v2/pokemon/?limit=12")
      .then((res) => res.json())
      .then(({ results }) => {
        setItems(results);
      });
  }, []);

  const pushPokemon = (pokemon) => {
    const isDuplicate = clicked.includes(pokemon);
    if (isDuplicate) {
      // If we have already added this pokemon, return before adding again to the list
      return console.log("You already selected ", pokemon);
    }
    // Else, this pokemon has not been clicked, so add it to state
    setClicked([...clicked, pokemon])
  }

  return (
    <div>
    {items.map(item => (
      <button onClick={() => pushPokemon(item.name)}>{item.name}</button>
    ))}
    <div>{JSON.stringify(clicked)}</div>
    </div>
  )
}

export default Cards
1
alex9552 22 czerwiec 2021, 19:13

Niezbyt dobre podejście, ale możesz spróbować tego:

const pushPokemon = (e) => {

    var pokemon = e.target.innerHTML
    if(!clicked.find(x=> x === pokemon))
    {
        setClicked([...clicked, pokemon])
    }
}

Tak więc sprawdzi, czy element istnieje i będzie działał tylko wtedy, gdy go tam nie ma.

0
arslanshahab 22 czerwiec 2021, 19:06

Możesz chcieć rozróżnić przyciski i wartości, ponieważ w grze pamięciowej zakładam, że dwa różne przyciski miałyby te same wartości.

const [buttons, setButtons] = useState([])
// ...
const pushPokemon = (e) => {
  const btn = e.target
  // if button already included, return
  if (buttons.includes(btn)) return;
  
  // add button to array
  setButtons([...buttons, btn])

  var pokemon = e.target.innerHTML
  setClicked([...clicked, pokemon])
}
0
Daniel 22 czerwiec 2021, 19:14