Se supone que debe ejecutar solo la función shuffleCards cuando hago clic en el botón, pero en su lugar también ejecuta las dos instrucciones console.log() , la anterior y la posterior a la función.
¿Por qué está pasando esto?
El código:
import { useState } from 'react'; const cardImages = [ {"text": "A"}, {"text": "B"}, {"text": "C"}, {"text": "D"}, {"text": "E"}, {"text": "F"}, ] function App() { const [cards, setCards] = useState([]); const [turns, setTurns] = useState(0); console.log("Cardssssssssss") const shuffleCards = () => { const shuffledCards = [...cardImages, ...cardImages] .sort(() => Math.random() - 0.5) .map((card) => ({ ...card, id: Math.random() })) setCards(shuffledCards); setTurns(0) // understand sort() method } // even though rahom bara lfunction rahom y'atfficha f onclick why console.log("Cards:", cards) return ( <div className="App text-center p-4 text-white bg-[black] h-[100vh] " > <h1 className='text-4xl font-bold ' >Magic Match</h1> <button onClick={shuffleCards} className='border-white border border-solid p-1 px-2 mt-4 ' > New Game </button> </divAl reaccionar cuando se procesa un componente, se ejecutan todas las funciones antes de la return , por lo que está llamando a shuffleCards() onClick pero antes de todo el código
entre function App() {
y return (
fue ejecutado,
por cierto, reemplace onClick={shuffleCards} por onClick={ () => { shuffleCards() } } para llamar solo cuando haga clic.
Ambos registros de la consola están en el cuerpo del componente y todo el cuerpo de la función de un componente de la función React es la función "renderizar". Estos registros son efectos secundarios no intencionales.
Verá que ambos registros ocurren cada vez que el componente se renderiza por cualquier motivo .
En este caso específico, cuando se hace clic en el botón y se invoca el controlador de devolución de llamada shuffleCards , se ponen en cola dos actualizaciones de estado de las cards y se activan los turns , lo que activará una representación de componentes después de que se procesen.
Por lo general, querrá colocar los efectos secundarios en el gancho useEffect con un nombre muy apropiado.
Ejemplo:
function App() { const [cards, setCards] = useState([]); const [turns, setTurns] = useState(0); useEffect(() => { console.log("Cardssssssssss"); }, []); // <-- empty dependency, runs once on component mount const shuffleCards = () => { const shuffledCards = [...cardImages, ...cardImages] .sort(() => Math.random() - 0.5) .map((card) => ({ ...card, id: Math.random() })); setCards(shuffledCards); setTurns(0); }; useEffect(() => { console.log("Cards:", cards); }, [cards]); // <-- cards dependency, run effect when cards updates return ( <div className="App text-center p-4 text-white bg-[black] h-[100vh] " > <h1 className='text-4xl font-bold ' >Magic Match</h1> <button onClick={shuffleCards} className='border-white border border-solid p-1 px-2 mt-4 ' > New Game </button> </div