Tengo un componente llamado RightTab como este
const RightTab = ({ data }) => { return ( <div className="RightTab flex__container " onClick={data.onClick}> <img src={data.icon} alt="Dashboard Icon" /> <p className="p__poppins">{data.name}</p> {data.dropDown === true ? ( <div className="dropdown__icon"> <img src={Assets.Arrow} alt="Arrow" /> </div> ) : ( <div className="nothing"></div> )} </div> ); }; export default RightTab;La pestaña tiene un estado activo en su CSS como este
.RightTab.active { background-color: var(--primaryGreen); }como has visto cambia de color cuando se añade una clase activa. Tengo una matriz en el componente principal que paso al componente secundario como accesorios. Aquí está la matriz
const dataArray = [ { name: "Dashboard", icon: Assets.Dashboard, dropDown: false, onClick: handleDashBoardClick, }, { name: "Inventory", icon: Assets.Inventory, dropDown: true, onClick: handleInventoryClick, }, { name: "Reports", icon: Assets.Reports, dropDown: true, onClick: handleReportsClick, }, ];Así es como paso los accesorios.
<RightTab data={dataArray[0]} /> <RightTab data={dataArray[1]} /> <RightTab data={dataArray[2]} />La propiedad de datos pasada al componente es un objeto que contiene una llamada de función como una de sus propiedades como esta. Tengo un atributo onclick en el contenedor principal de los componentes secundarios que se supone que debe llamar a la función respectiva.
La función es lo que agrega la clase activa para hacer que el fondo cambie de color. Sin embargo, cada vez que hago clic en el componente , solo cambia el fondo de la primera aparición . Y como habrás notado, llamo al componente tres veces. No importa en qué componente haga clic, solo los primeros cambios de fondo .
Aquí hay un ejemplo de la función que está en el objeto prop.
const handleDashBoardClick = () => { const element = document.querySelector(".RightTab"); element.classList.toggle("active"); };No entiendo lo que estoy haciendo mal. ¿Qué otro enfoque puedo utilizar?
Aunque use el componente 3 veces, no significa que un cambio que realice en uno de los componentes se reflejará en los otros 2, a menos que use específicamente un parámetro de estado que se pasa a los 3.
Además, no se recomienda la forma en que agrega la clase activa, ya que mezcla reaccionar con js puro para manejar los nombres de clase CSS.
Recomendaría tener un controlador de un solo clic que alterna la clase activa para todos los componentes n RightTab :
const MainComponent = () => { const [classNames, setClassNames] = useState([]); const handleClick = (name) => { const toggledActiveClass = classNames.indexOf('active') === -1 ? classNames.concat(['active']) : classNames.filter((className) => className !== 'active'); setClassNames(toggledActiveClass); switch (name) { case 'Dashboard'; // do something break; case 'Inventory': // .... break; } } const dataArray = [ { name: "Dashboard", icon: Assets.Dashboard, dropDown: false, onClick: handleClick.bind(null, 'Dashboard'), }, { name: "Inventory", icon: Assets.Inventory, dropDown: true, onClick: handleClick.bind(null, 'Inventory'), }, { name: "Reports", icon: Assets.Reports, dropDown: true, onClick: handleClick.bind(null, 'Reports'), }, ]; return ( <> {dataArray.map((data) => <RightTab key={data.name} data={data} classNames={classNames} />)} </> ); }; const RightTab = ({ data, classNames }) => { return ( <div className={classNames.concat(['RightTab flex__container']).join(' ')} onClick={data.onClick}> <img src={data.icon} alt="Dashboard Icon" /> <p className="p__poppins">{data.name}</p> {data.dropDown === true ? ( <div className="dropdown__icon"> <img src={Assets.Arrow} alt="Arrow" /> </div> ) : ( <div className="nothing"></div> )} </div> ); };