Хорошо, я создаю веб-приложение, используя реакцию, и у меня есть компонент под названием срез, который содержит два компонента проекта, и я хотел бы изменить их ширину на основе события наведения. я знаю, что класс добавляется в список классов, но стили не применяются. Я пытался изменить другие стили в качестве индикаторов, чтобы увидеть, была ли это просто проблема с шириной или списком классов, но это тоже не сработало.
срез.js:
import { useState, useEffect } from "react";
import Project from "./Project";
import "./Slice.css";
import { v4 as uuidv4 } from "uuid";
export default function Slice(props) {
const data = props.sliceData.projects;
const [projectElements, setProjectElements] = useState([]);
const projectUIDs = [uuidv4(), uuidv4()];
useEffect(() => {
const elements = [
document.getElementById(projectUIDs[0]),
document.getElementById(projectUIDs[1]),
];
setProjectElements(elements);
return () => {
elements.forEach((element, index) => {
if (element) {
element.removeEventListener("mouseover", () =>
handleMouseOver(index)
);
element.removeEventListener("mouseout", () =>
handleMouseOut(index)
);
}
});
};
}, []);
const handleMouseOver = (index) => {
projectElements[index].classList.add("maximized");
projectElements[index ^ 1].classList.add("minimized");
};
const handleMouseOut = (index) => {
projectElements[index].classList.remove("maximized");
projectElements[index ^ 1].classList.remove("minimized");
};
const generateProjects = () => {
return data.map((project, index) => (
<Project
key = {uuidv4()}
uid = {projectUIDs[index]}
projectData = {project}
onMouseEnter = {() => handleMouseOver(index)}
onMouseLeave = {() => handleMouseOut(index)}
/>
));
};
return <div className = "slice">{generateProjects()}</div>;
}
Срез.css:
.slice {
height: 50vh;
width: 100%;
display: flex;
}
.projectWrapper {
display: flex;
justify-content: space-around;
align-items: center;
color: black;
padding: 2rem;
overflow: hidden;
transition: flex-grow 0.5s ease-in-out;
width: 100%; /* Ensure each projectWrapper occupies the full width */
}
.projectWrapper img {
flex: 1; /* Use flex shorthand to distribute space equally */
max-width: 50%; /* Set maximum width for the image */
}
.projectWrapper h1 {
flex: 1; /* Use flex shorthand to distribute space equally */
font-size: 2rem;
font-weight: 700;
max-width: 40%; /* Set maximum width for the h1 element */
}
.minimized{
flex-grow: 0;
}
.maximized{
flex-grow: 1;
}
@media (max-aspect-ratio: 155/100) {
.slice{
flex-direction: column;
height: fit-content;
}
.projectWrapper{
height: 50vh;
}
}
@media (max-width: 450px) {
.projectWrapper{
flex-direction: column;
align-items: center;
}
.projectWrapper h1{
text-align: center;
width: 80%;
max-width: none;
}
.projectWrapper img{
width: 80%;
max-width: none;
}
}
я надеялся, что стили внутри классов .minimized и .maximized будут применены к компонентам проекта при наведении курсора мыши
В React вам следует стараться, насколько это возможно, избегать прямых манипуляций с DOM и вместо этого использовать состояние и реквизиты компонента. Более удобный для React способ обработки событий наведения с использованием состояния:
export default function Slice(props) {
const data = props.sliceData.projects;
const [hoverIndex, setHoverIndex] = useState(null);
const handleMouseOver = (index) => {
setHoverIndex(index);
};
const handleMouseOut = () => {
setHoverIndex(null);
};
const generateProjects = () => {
return data.map((project, index) => (
<Project
key = {uuidv4()}
projectData = {project}
isHovered = {hoverIndex === index}
onMouseEnter = {() => handleMouseOver(index)}
onMouseLeave = {handleMouseOut}
/>
));
};
return <div className = "slice">{generateProjects()}</div>;
}
Обратите внимание на новый реквизит для компонента Project
— isHovered
. На основе этого вы можете добавить класс в компонент Project
, например:
<div className = {isHovered ? "maximized" : "minimized" }></div>
Никогда не следует использовать getElementById в реакции, а сохранение его в состоянии имеет еще меньше смысла. Я бы рекомендовал начать с учебника по реагированию.