반응 애니메이션 onDestroy(DOM에서 제거됨)
25275 단어 csstypescriptreactjavascript
저는 일반적으로 React 구성 요소 또는 JSX 요소에 일부 fadeIn/fadeOut 전환을 적용할 때 문제에 직면합니다. 구성 요소/요소가 DOM에서 제거되면 더 이상 전환을 적용할 수 없기 때문입니다.
매초 1씩 증가하는 카운터가 있는 기본적인 React 앱을 작성해 봅시다.
카운터를 표시하고 그 아래에 카운트가 3으로 나누어질 때마다 반응 이미지를 표시합니다.
데모here .
// Disable React Strict mode for this example
function App() {
const [count, setCount] = useState(0);
const [isDivisibleByThree, setIsDivisibleByThree] = useState(false);
useEffect(() => {
if (count !== 0 && count % 3 === 0) setIsDivisibleByThree(true);
}, [count]);
useEffect(() => {
setInterval(() => {
setCount((p) => (p += 1));
}, 1000);
}, []);
return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "50px",
alignItems: "center",
justifyContent: "center",
}}
>
<div>
<h1>count is {count}</h1>
</div>
<p>
{isDivisibleByThree && (
<img ref={imageRef} src={reactLogo} alt="react logo"/>
)}
</p>
</div>
);
}
다음 CSS를 사용하여
<img>
가 표시될 때마다 애니메이션을 적용할 수 있습니다.이렇게 하면 이미지가 처음 나타날 때 슬라이드 인 애니메이션이 위에서 아래로 이동합니다.
img {
animation: slide-in 0.5s ease-in-out;
}
p {
height: 5rem;
width: 5rem;
}
@keyframes slide-in {
0% {
opacity: 0;
transform: translateY(-50%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
그래서...
<img>
요소가 DOM에서 제거될 때 어떻게 애니메이션을 적용할 수 있습니까?useHandleDestroyAnimated
라는 사용자 정의 후크를 생성해 보겠습니다. 이 후크는 제거 시 애니메이션을 적용하려는 HTML 요소의 참조(useRef
후크에서)를 허용합니다.isDivisibleByThree 상태를 false로 설정하여
<img>
를 숨기기 전에 1000ms 후에 소멸을 애니메이션한 다음 상태를 false로 설정합니다.async function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function useHandleDestroyAnimated<T extends HTMLElement>(
ref: MutableRefObject<T | null>
): [boolean, (_: boolean) => void] {
const [state, setState] = useState(false);
// everytime the state or ref change, if state is true, we animate the destroy of the component.
useEffect(() => {
if (state) {
handleDeletion(ref);
}
}, [ref, state]);
function handleDeletion<T extends HTMLElement>(
element: MutableRefObject<T | null>
) {
const style = element?.current?.style;
if (!style) return;
sleep(1000).then(() => {
style.transition = "all 0.5s";
style.transform = "translateY(-50%)";
style.opacity = "0";
sleep(1000).then(() => {
setState(false);
});
});
}
return [state, setState];
}
useRef
후크의 ref를 App.tsx에 추가해 보겠습니다.const imageRef = useRef<HTMLImageElement | null>(null);
.....
.....
.....
<p>
{isDivisibleByThree && (
<img ref={imageRef} src={reactLogo} alt="react logo" />
)}
</p>
최종 코드는 다음과 같습니다.
import { useEffect, useState, MutableRefObject, useRef } from "react";
import reactLogo from "./assets/react.svg";
import "./App.css";
async function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
const styles = Object.freeze({
opacity: "0",
transform: "translateY(-50%)",
transition: "all 0.5s",
});
function useHandleDestroyAnimated<T extends HTMLElement>(
ref: MutableRefObject<T | null>
): [boolean, (_: boolean) => void] {
const [state, setState] = useState(false);
useEffect(() => {
if (state) {
handleDeletion(ref);
}
}, [ref, state]);
function handleDeletion<T extends HTMLElement>(
element: MutableRefObject<T | null>
) {
const style = element?.current?.style;
if (!style) return;
sleep(1000).then(() => {
style.transition = styles.transition;
style.transform = styles.transform;
style.opacity = styles.opacity;
sleep(1000).then(() => {
setState(false);
});
});
}
return [state, setState];
}
function App() {
const [count, setCount] = useState(0);
const imageRef = useRef<HTMLImageElement | null>(null);
const [isDivisibleByThree, setIsDivisibleByThree] =
useHandleDestroyAnimated(imageRef);
useEffect(() => {
if (count !== 0 && count % 3 === 0) setIsDivisibleByThree(true);
}, [count]);
useEffect(() => {
setInterval(() => {
setCount((p) => (p += 1));
}, 1000);
}, []);
return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "50px",
alignItems: "center",
justifyContent: "center",
}}
>
<div>
<span>count is {count}</span>
</div>
<p>
{isDivisibleByThree && (
<img ref={imageRef} src={reactLogo} alt="react logo" />
)}
</p>
</div>
);
}
export default App;
이 정보가 도움이 되었기를 바랍니다.
다음에서 나를 팔로우할 수 있습니다.
Reference
이 문제에 관하여(반응 애니메이션 onDestroy(DOM에서 제거됨)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aspnxdd/react-animation-ondestroy-removed-from-the-dom-53pd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)