Home > Back-end >  How to add styles to individual elements in react using e.target, when a button is clicked?
How to add styles to individual elements in react using e.target, when a button is clicked?

Time:05-07

I am trying to add styles to the inidividual elements. I want when an individual div( is clicked to make sure that the paragraph of the specific changes from display: none to dislay:block. But the problem is, when I click only on one , all the paragraph text is displayed. here is the css below:


.cards{
    background-color: red;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 20vh;
}

[class*=cardDisplay]{
    height: 80%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 200px;
    background: black; 
    color: white;
    margin: auto;
}

[class*=card-content]{
    display: none;
}

[class*=card-content-2]{
    display: block;
}

and the react.js file:

import React from 'react';
import {useState} from "react";
import "./game.css";

function Game() {
    const [styling, setStyling] = useState("card-content")

    const handleClick = () => {
        setStyling("card-content-2")
    }

  return (
      <div className="cards">
          <div className="cardDisplay card-1" onClick={handleClick}>
              <p className={styling}>Win</p>
          </div>
          <div className="cardDisplay card-2" onClick={handleClick}>
              <p className={styling}>Sorry, No Win</p>
          </div>
          <div className="cardDisplay card-3" >
              <p className={styling} onClick={handleClick}>Sorry, No Win</p>
          </div>
      </div>
  )
}

CodePudding user response:

You're using only one styling that you're applying to all paragraphs. If you want distinct styling for each paragraph, you have to hold that state separately for each paragraph.

Either:

  1. Make the div paragraph a component that holds its own state, or

  2. Have multiple styling state members (perhaps an array).

I would lean toward the first:

function Card({className = "", children}) {
    const [styling, setStyling] = useState("card-content");

    const handleClick = () => {
        setStyling("card-content-2")
    };

    return (
        <div className={`cardDisplay ${className}`} onClick={handleClick}>
            <p className={styling}>{children}</p>
        </div>
    );
};

function Game() {
    return (
        <div className="cards">
            <Card className="card-1">Win</Card>
            <Card className="card-2">Sorry, No Win</Card>
            <Card className="card-3">Sorry, No Win</Card>
        </div>
    );
}

There's lots of ways to spin that, but that's the basic idea.

But there's also an argument for the cards being an array of objects with state; here's an example with the results randomized when the component is first mounted:

function makeCards() {
    const num = 3;
    const win = Math.floor(Math.random() * num);
    return Array.from({length: 3}, (_, index) => ({
        id: `card-${index}`,
        result: index === win ? "Win" : "Sorry, No Win",
        showing: false,
    }));
}

function Game() {
    const [cards, setCards] = useState(makeCards);
    const handleClick = (event) => {
        const id = event.currentTarget.getAttribute("data-id");
        setCards(prevCards => {
            const newCards = prevCards.map(card => {
                if (card.id === id) {
                    return {...card, showing: true};
                }
                return card;
            });
            return newCards;
        });
    };
    return (
        <div className="cards">
            {cards.map(({id, result, showing}) => (
                <div key={id} data-id={id} className={`cardDisplay ${id}`} onClick={handleClick}>
                    <p className={showing ? "card-content" : "card-content-2"}>{result}</p>
                </div>
            ))}
        </div>
    );
}

CodePudding user response:

This may help you. It really works........

import React from 'react';
import {useState} from "react";
import "./game.css";

function Game() {
  const handleClick = (e) => {
    e.target.firstChild?.classList?.remove("card-content");
    e.target.firstChild?.classList?.add("card-content-2");
  };

  return (
    <div className="cards">
      <div className="cardDisplay card-1" onClick={handleClick}>
        <p className="card-content">Win</p>
      </div>
      <div className="cardDisplay card-2" onClick={handleClick}>
        <p className="card-content">Sorry, No Win</p>
      </div>
      <div className="cardDisplay card-3" onClick={handleClick}>
        <p className="card-content">Sorry, No Win</p>
      </div>
    </div>
  );
}
  • Related