Estoy tratando de agregar estilos a los elementos individuales. Cuando se hace clic en un div individual, quiero asegurarme de que el párrafo de los cambios específicos de display: none a dislay:block. Pero el problema es que, cuando hago clic solo en uno, se muestra todo el texto del párrafo. aquí está el CSS a continuación:
.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; }y el archivo react.js:
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> ) }Está utilizando solo un styling que está aplicando a todos los párrafos. Si desea un estilo distinto para cada párrafo, debe mantener ese estado por separado para cada párrafo.
O:
Hacer que el div + paragraph sea un componente que mantenga su propio estado, o
Tenga varios miembros de estado de styling (quizás una matriz).
Yo me inclinaría por lo primero:
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> ); }Hay muchas maneras de girar eso, pero esa es la idea básica.
Pero también hay un argumento para que las tarjetas sean una matriz de objetos con estado; aquí hay un ejemplo con los resultados aleatorios cuando el componente se monta por primera vez:
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> ); }Esto puede ayudarte. Realmente funciona........
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> ); }Lo que está haciendo actualmente es cambiar el estilo de cada una de las etiquetas p .
Le aconsejaré que tenga una clase personalizada que devuelva su etiqueta div que contiene la etiqueta p
Tenga una matriz de Objetos que contengan el estilo de la tarjeta y el texto que se mostrará. Asigne a través de la matriz y devuelva el estilo y las etiquetas en consecuencia. Como se muestra a continuación.
manejar los eventos de clic en el div personalizado.
import React from 'react'; import "./game.css"; import MyDiv from './MyDiv'; const cards = [{ cardStyle: 'card-1', text: "Win" }, { cardStyle: 'card-2', text: 'Sorry, No Win' }, { cardStyle: 'card-3', text: 'Sorry, NoWin' }]; function Game() { return ( <div className="cards"> {cards.map((card, index) => (<MyDiv cardNumberStyle={card.cardStyle} key={index} textToDisplay={card.text} />)) } </div> ); } export default Game;Y luego MyDiv es:
import React, { useState } from "react"; const MyDiv = ({ cardNumberStyle, textToDisplay }) => { const [styling, setStyling] = useState('card-content'); ///Handles clicks const handleClick = () => { //conditionally change the styling if (styling === 'card-content') setStyling('card-content-2') else setStyling('card-content'); } return ( <div className={`cardDisplay ${cardNumberStyle}`} onClick={handleClick}> <p className={styling}>{textToDisplay}</p> </div> ); } export default MyDiv;