El título lo resume bastante bien. Quiero eliminar un nombre de clase de un elemento una vez que se presiona un botón, y para esto, he intentado usar ganchos useState , una función normal y estoy usando onClick en el botón para llamar a esta función/setUseState, pero la lista className es Siempre lo mismo. Aquí hay una muestra de mi código:
function TileBoard() { const [openTileVisible, setOpenTileVisible] = useState(true); const [shuffler, setShuffler] = useState(0); const yellowTileIds = [9, 10, 11, 12, 15, 23, 24, 25, 33, 36, 37, 38, 39]; let initialTiles = []; for (let i = 0; i <= 48; i++) { if (i === 48) { initialTiles.push(<Tile key={i} number={i} id={'openTile'} className={openTileVisible ? 'tile-black tile' : 'tile'}/>); } else { if (yellowTileIds.includes(i)) { initialTiles.push(<Tile key={i} number={i} className={'tile-yellow tile'}/>); } else { initialTiles.push(<Tile key={i} number={i} className={'tile-black tile'}/>); } } } const [tiles, setTiles] = useState(initialTiles); return ( <div className={'game'}> <div key={shuffler} className={'board'}> <div className={'tiles'}> {tiles} </div> </div> <button onClick={() => { setOpenTileVisible(false); shuffleArray(); }}>SHUFFLE</button> </div> ); }Por alguna razón, esto no elimina la clase, aunque se cambie el useState. ¿Hice algo mal con el atributo className cuando creé el objeto?
Aquí está el método aleatorio:
function shuffleArray() { let array = tiles; for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = array[j]; array[j] = temp; } console.log(array); setTiles(array); // Using this to force the Rerender, since React doesn't count // change in element order in array as a reason to rerender. setShuffler(shuffler + 1); }Haga que los tiles sean el valor calculado (y memorizado) de useMemo en lugar de usarlo como estado, esto actualiza el valor cuando cambian las dependencias.
import React, { useMemo } from "react"; const tiles = useMemo(() => { const tiles = []; for (let i = 0; i <= 48; i++) { if (i === 48) { tiles.push( <Tile key={i} number={i} id={"openTile"} className={openTileVisible ? "tile-black tile" : "tile"} /> ); } else { if (tiles.includes(i)) { tiles.push( <Tile key={i} number={i} className={"tile-yellow tile"} /> ); } else { tiles.push(<Tile key={i} number={i} className={"tile-black tile"} />); } } } return tiles; }, [openTileVisible, shuffler]);let array = tiles; Con esta asignación, siempre se hace referencia a la array como la misma matriz de tiles , lo que va en contra de la regla de inmutabilidad en React .
Junto con esto, le sugiero que use React.cloneElement() para clonar los componentes de mosaico que ayudan a forzar la reproducción de sus mosaicos también.
Deberías modificarlo como a continuación.
function shuffleArray() { let array = [...tiles]; //assign a new tiles' array for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = React.cloneElement(array[j]); //clone your tile array[j] = React.cloneElement(temp); //clone your tile } console.log(array); setTiles(array); //setShuffler(shuffler + 1); //you don't need to use it anymore because the array modification has been forcing the re-rendering }