Home > database >  Why are the two console.log executed when I click the button even though they aren't inside the
Why are the two console.log executed when I click the button even though they aren't inside the

Time:07-24

It is supposed to execute only the function shuffleCards when I click the button but instead it also executes the two console.log() statements, the one before and after the function.

Why is this happening?

The code:

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>
    </div

CodePudding user response:

In react when a component render, all the functions before the return are executed, so you are calling shuffleCards() onClick but before all the code

between function App() {

and return (

got executed,

btw replace onClick={shuffleCards} by onClick={ () => { shuffleCards() } } to call in only when click !

CodePudding user response:

Both console logs are in the component body and the entire function body of a React function component is the "render" function. These logs are unintentional side-effects.

You will see both logs occur any time the component renders for any reason at all.

In this specific case when the button is clicked and the shuffleCards callback handler is invoked, it enqueues two state updates to cards and turns which will trigger a component rerender after they are processed.

Generally you will want to place side-effects into the very appropriately named useEffect hook.

Example:

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
  • Related